You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ha...@apache.org on 2017/09/30 23:17:53 UTC

[royale-asjs] branch feature/validation created (now 5be4088)

This is an automated email from the ASF dual-hosted git repository.

harbs pushed a change to branch feature/validation
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git.


      at 5be4088  First stab at validation Copied from the mx classes and cleaned up to remove compiler errors Still could use cleanup Need to add test No localization features (need to get resource bundles working for that)

This branch includes the following new commits:

     new 5be4088  First stab at validation Copied from the mx classes and cleaned up to remove compiler errors Still could use cleanup Need to add test No localization features (need to get resource bundles working for that)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@royale.apache.org" <co...@royale.apache.org>'].

[royale-asjs] 01/01: First stab at validation Copied from the mx classes and cleaned up to remove compiler errors Still could use cleanup Need to add test No localization features (need to get resource bundles working for that)

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

harbs pushed a commit to branch feature/validation
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 5be4088ac497a28e97ca886908b4b485082ee5b5
Author: Harbs <ha...@in-tools.com>
AuthorDate: Sun Oct 1 02:17:49 2017 +0300

    First stab at validation
    Copied from the mx classes and cleaned up to remove compiler errors
    Still could use cleanup
    Need to add test
    No localization features (need to get resource bundles working for that)
---
 .../projects/Core/src/main/flex/CoreClasses.as     |   12 +
 .../flex/utils/validation/CreditCardValidator.as   | 1151 ++++++++++++++++
 .../validation/CreditCardValidatorCardType.as      |   96 ++
 .../flex/utils/validation/CurrencyValidator.as     | 1299 ++++++++++++++++++
 .../validation/CurrencyValidatorAlignSymbol.as     |   79 ++
 .../apache/flex/utils/validation/DateValidator.as  | 1446 ++++++++++++++++++++
 .../apache/flex/utils/validation/EmailValidator.as |  834 +++++++++++
 .../flex/utils/validation/IResourceManager.as      |   41 +
 .../org/apache/flex/utils/validation/IValidator.as |  118 ++
 .../flex/utils/validation/IValidatorListener.as    |  130 ++
 .../flex/utils/validation/NumberValidator.as       | 1197 ++++++++++++++++
 .../utils/validation/NumberValidatorDomainType.as  |   64 +
 .../flex/utils/validation/PhoneNumberValidator.as  |  425 ++++++
 .../utils/validation/RegExpValidationResult.as     |  146 ++
 .../flex/utils/validation/RegExpValidator.as       |  434 ++++++
 .../flex/utils/validation/ResourceManager.as       |   91 ++
 .../utils/validation/SocialSecurityValidator.as    |  433 ++++++
 .../flex/utils/validation/StringValidator.as       |  390 ++++++
 .../flex/utils/validation/ValidationResult.as      |  146 ++
 .../flex/utils/validation/ValidationResultEvent.as |  223 +++
 .../org/apache/flex/utils/validation/Validator.as  | 1167 ++++++++++++++++
 .../flex/utils/validation/ZipCodeValidator.as      |  807 +++++++++++
 .../utils/validation/ZipCodeValidatorDomainType.as |   75 +
 23 files changed, 10804 insertions(+)

diff --git a/frameworks/projects/Core/src/main/flex/CoreClasses.as b/frameworks/projects/Core/src/main/flex/CoreClasses.as
index 52cdef7..c291da5 100644
--- a/frameworks/projects/Core/src/main/flex/CoreClasses.as
+++ b/frameworks/projects/Core/src/main/flex/CoreClasses.as
@@ -224,6 +224,18 @@ internal class CoreClasses
 	{
 	    import org.apache.flex.core.IFlexJSElement; IFlexJSElement;
 	}
+
+	//Validation
+	import org.apache.flex.utils.validation.CreditCardValidator; CreditCardValidator;
+	import org.apache.flex.utils.validation.CurrencyValidator; CurrencyValidator;
+	import org.apache.flex.utils.validation.DateValidator; DateValidator;
+	import org.apache.flex.utils.validation.EmailValidator; EmailValidator;
+	import org.apache.flex.utils.validation.NumberValidator; NumberValidator;
+	import org.apache.flex.utils.validation.PhoneNumberValidator; PhoneNumberValidator;
+	import org.apache.flex.utils.validation.RegExpValidator; RegExpValidator;
+	import org.apache.flex.utils.validation.SocialSecurityValidator; SocialSecurityValidator;
+	import org.apache.flex.utils.validation.StringValidator; StringValidator;
+	import org.apache.flex.utils.validation.ZipCodeValidator; ZipCodeValidator;
 }
 
 }
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidator.as
new file mode 100644
index 0000000..f2e3801
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidator.as
@@ -0,0 +1,1151 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+	// [ResourceBundle("validators")]
+
+	/**
+	 *  The CreditCardValidator class validates that a credit card number
+	 *  is the correct length, has the correct prefix, and passes
+	 *  the Luhn mod10 algorithm for the specified card type. 
+	 *  This validator does not check whether the credit card
+	 *  is an actual active credit card account.
+	 *
+	 *  <p>You can specify the input to the CreditCardValidator in two ways:</p>
+	 *  <ul>
+	 *    <li>Use the <code>cardNumberSource</code> and
+	 *    <code>cardNumberProperty</code> properties to specify
+	 *    the location of the credit card number, and the 
+	 *    <code>cardTypeSource</code> and <code>cardTypeProperty</code> properties
+	 *    to specify the location of the credit card type to validate.</li>
+	 *    <li>Use the <code>source</code> and 
+	 *    <code>property</code> properties to specify a single Object.
+	 *    The Object should contain the following fields:
+	 *    <ul>
+	 *        <li><code>cardType</code> - Specifies the type
+	 *        of credit card being validated. 
+	 *         <p>In MXML, use the values: <code>"American Express"</code>, 
+	 *            <code>"Diners Club"</code>, <code>"Discover"</code>, 
+	 *            <code>"MasterCard"</code>, or <code>"Visa"</code>.</p>
+	 *         <p>In ActionScript, use the static constants
+	 *            <code>CreditCardValidatorCardType.MASTER_CARD</code>, 
+	 *            <code>CreditCardValidatorCardType.VISA</code>, or
+	 *            <code>CreditCardValidatorCardType.AMERICAN_EXPRESS</code> 
+	 *            <code>CreditCardValidatorCardType.DISCOVER</code>, or
+	 *            <code>CreditCardValidatorCardType.DINERS_CLUB</code>.</p>
+	 *          </li>
+	 *       <li><code>cardNumber</code> - Specifies the number of the card
+	 *       being validated.</li>
+	 *     </ul>
+	 *    </li>
+	 *  </ul>
+	 *  
+	 *  <p>To perform the validation, it uses the following guidelines:</p>
+	 *  <p>Length:</p>
+	 *  <ol>
+	 *    <li>Visa: 13 or 16 digits</li> 
+	 *    <li>MasterCard: 16 digits</li> 
+	 *    <li>Discover: 16 digits</li> 
+	 *    <li>American Express: 15 digits</li> 
+	 *    <li>Diners Club: 14 digits or 16 digits if it also functions as MasterCard</li>
+	 *  </ol>
+	 *  Prefix:
+	 *  <ol>
+	 *    <li>Visa: 4</li> 
+	 *    <li>MasterCard: 51 to 55</li>
+	 *    <li>Discover: 6011</li>
+	 *    <li>American Express: 34 or 37</li>
+	 *    <li>Diners Club: 300 to 305, 36 or 38, 51 to 55</li>
+	 *  </ol>
+	 *  
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:CreditCardValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>
+	 *  
+	 *  <pre>
+	 *  &lt;mx:CreditCardValidator
+	 *    allowedFormatChars=" -" 
+	 *    cardNumberListener="<i>Object specified by cardNumberSource</i>"
+	 *    cardNumberProperty="<i>No default</i>"
+	 *    cardNumberSource="<i>No default</i>"
+	 *    cardTypeListener="<i>Object specified by cardTypeSource</i>"
+	 *    cardTypeProperty="<i>No default</i>"
+	 *    cardTypeSource="<i>No default</i>"
+	 *    invalidCharError= "Invalid characters in your credit card number. (Enter numbers only.)"
+	 *    invalidNumberError="The credit card number is invalid." 
+	 *    noNumError="No credit card number is specified."
+	 *    noTypeError="No credit card type is specified or the type is not valid." 
+	 *    wrongLengthError="Your credit card number contains the wrong number of digits." 
+	 *    wrongTypeError="Incorrect card type is specified." 
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @see mx.validators.CreditCardValidatorCardType
+	 *  
+	 *  @includeExample examples/CreditCardValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class CreditCardValidator extends Validator
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Convenience method for calling a validator.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The CreditCardValidator instance.
+		 *
+		 *  @param value A field to validate, which must contain
+		 *  the following fields:
+		 *  <ul>
+		 *    <li><code>cardType</code> - Specifies the type of credit card being validated. 
+		 *    Use the static constants
+		 *    <code>CreditCardValidatorCardType.MASTER_CARD</code>, 
+		 *    <code>CreditCardValidatorCardType.VISA</code>,
+		 *    <code>CreditCardValidatorCardType.AMERICAN_EXPRESS</code>,
+		 *    <code>CreditCardValidatorCardType.DISCOVER</code>, or
+		 *    <code>CreditCardValidatorCardType.DINERS_CLUB</code>.</li>
+		 *    <li><code>cardNumber</code> - Specifies the number of the card
+		 *    being validated.</li></ul>
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the value parameter. 
+		 *  For example, if the <code>value</code> parameter
+		 *  specifies value.date, the <code>baseField</code> value is "date".
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validateCreditCard(validator:CreditCardValidator,
+												value:Object,
+												baseField:String):Array
+		{
+			var results:Array = [];
+			
+			// Resource-backed properties of the validator.
+			var allowedFormatChars:String = validator.allowedFormatChars;
+
+			var resourceManager:IResourceManager = ResourceManager.getInstance();
+
+			var baseFieldDot:String = baseField ? baseField + "." : "";
+			
+			var valid:String = DECIMAL_DIGITS + allowedFormatChars;
+			var cardType:String = null;
+			var cardNum:String = null;
+			var digitsOnlyCardNum:String = "";
+			var message:String;
+
+			var n:int;
+			var i:int;
+			
+			try 
+			{
+				cardType = String(value.cardType);
+			}
+			catch(e:Error)
+			{
+				// Use the default value and move on
+				message = resourceManager.getString(
+					"validators", "missingCardType");
+				throw new Error(message);
+			}
+			
+			try 
+			{
+				cardNum = value.cardNumber;
+			}
+			catch(f:Error)
+			{
+				// Use the default value and move on
+				message = resourceManager.getString(
+					"validators", "missingCardNumber");
+				throw new Error(message);
+			}
+			
+			if (validator.required)
+			{
+				if (cardType.length == 0)
+				{
+					results.push(new ValidationResult(
+						true, baseFieldDot + "cardType",
+						"requiredField", validator.requiredFieldError));
+				}
+
+				if (!cardNum)
+				{
+					results.push(new ValidationResult(
+						true, baseFieldDot + "cardNumber",
+						"requiredField", validator.requiredFieldError));
+				}
+			}
+			
+			n = allowedFormatChars.length;
+			for (i = 0; i < n; i++)
+			{
+				if (DECIMAL_DIGITS.indexOf(allowedFormatChars.charAt(i)) != -1)
+				{
+					message = resourceManager.getString(
+						"validators", "invalidFormatChars");
+					throw new Error(message);
+				}
+			}
+			
+			if (!cardType)
+			{
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardType",
+					"noType", validator.noTypeError));
+			}
+			else if (cardType != CreditCardValidatorCardType.MASTER_CARD &&
+					cardType != CreditCardValidatorCardType.VISA &&
+					cardType != CreditCardValidatorCardType.AMERICAN_EXPRESS &&
+					cardType != CreditCardValidatorCardType.DISCOVER &&
+					cardType != CreditCardValidatorCardType.DINERS_CLUB)
+			{
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardType",
+					"wrongType", validator.wrongTypeError));
+			}
+
+			if (!cardNum)
+			{
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardNumber",
+					"noNum", validator.noNumError));
+			}
+
+			if (cardNum)
+			{
+				n = cardNum.length;
+				for (i = 0; i < n; i++)
+				{
+					var temp:String = "" + cardNum.substring(i, i + 1);
+					if (valid.indexOf(temp) == -1)
+					{
+						results.push(new ValidationResult(
+							true, baseFieldDot + "cardNumber",
+							"invalidChar", validator.invalidCharError));
+					}
+					if (DECIMAL_DIGITS.indexOf(temp) != -1)
+						digitsOnlyCardNum += temp;
+				}
+			}
+			
+			if (results.length > 0)
+				return results;
+
+			var cardNumLen:int = digitsOnlyCardNum.toString().length;
+			var correctLen:Number = -1;
+			var correctLen2:Number = -1;
+			var correctPrefixArray:Array = [];
+			
+			// diner club cards with a beginning digit of 5 need to be treated as
+			// master cards. Go to the following link for more info.
+			// http://www.globalpaymentsinc.com/myglobal/industry_initiatives/mc-dc-canada.html
+			if (cardType == CreditCardValidatorCardType.DINERS_CLUB &&
+				digitsOnlyCardNum.charAt(0) == "5")
+			{
+				cardType = CreditCardValidatorCardType.MASTER_CARD;
+			}
+			
+			switch (cardType)
+			{
+				case CreditCardValidatorCardType.MASTER_CARD:
+				{
+					correctLen = 16;
+					correctPrefixArray.push("51");
+					correctPrefixArray.push("52");
+					correctPrefixArray.push("53");
+					correctPrefixArray.push("54");
+					correctPrefixArray.push("55");
+					break;
+				}
+
+				case CreditCardValidatorCardType.VISA:
+				{
+					correctLen = 13;
+					correctLen2 = 16;
+					correctPrefixArray.push("4");
+					break;
+				}
+
+				case CreditCardValidatorCardType.AMERICAN_EXPRESS:
+				{
+					correctLen = 15;
+					correctPrefixArray.push("34");
+					correctPrefixArray.push("37");
+					break;
+				}
+
+				case CreditCardValidatorCardType.DISCOVER:
+				{
+					correctLen = 16;
+					correctPrefixArray.push("6011");
+					break;
+				}
+
+				case CreditCardValidatorCardType.DINERS_CLUB:
+				{
+					correctLen = 14;
+					correctPrefixArray.push("300");
+					correctPrefixArray.push("301");
+					correctPrefixArray.push("302");
+					correctPrefixArray.push("303");
+					correctPrefixArray.push("304");
+					correctPrefixArray.push("305");
+					correctPrefixArray.push("36");
+					correctPrefixArray.push("38");
+					break;
+				}
+
+				default:
+				{
+					results.push(new ValidationResult(
+						true, baseFieldDot + "cardType",
+						"wrongType", validator.wrongTypeError));
+					return results;
+				}
+			}
+
+			if ((cardNumLen != correctLen) && (cardNumLen != correctLen2)) 
+			{ 
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardNumber",
+					"wrongLength", validator.wrongLengthError));
+				return results;
+			}
+
+			// Validate the prefix
+			var foundPrefix:Boolean = false;
+			for (i = correctPrefixArray.length - 1; i >= 0; i--)
+			{
+				if (digitsOnlyCardNum.indexOf(correctPrefixArray[i]) == 0)
+				{
+					foundPrefix = true;
+					break;
+				}
+			}
+
+			if (!foundPrefix)
+			{
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardNumber",
+					"invalidNumber", validator.invalidNumberError));
+				return results;
+			}
+
+			// Implement Luhn formula testing of this.cardNumber
+			var doubledigit:Boolean = false;
+			var checkdigit:int = 0;
+			var tempdigit:int;
+			for (i = cardNumLen - 1; i >= 0; i--)
+			{
+				tempdigit = Number(digitsOnlyCardNum.charAt(i));
+				if (doubledigit)
+				{
+					tempdigit *= 2;
+					checkdigit += (tempdigit % 10);
+					if ((tempdigit / 10) >= 1.0)
+						checkdigit++;
+					doubledigit = false;
+				}
+				else
+				{
+					checkdigit = checkdigit + tempdigit;
+					doubledigit = true;
+				}
+			}
+
+			if ((checkdigit % 10) != 0)
+			{
+				results.push(new ValidationResult(
+					true, baseFieldDot + "cardNumber",
+					"invalidNumber", validator.invalidNumberError));
+				return results;
+			}
+
+			return results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function CreditCardValidator()
+		{
+			super();
+
+			subFields = [ "cardNumber", "cardType" ];
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  actualListeners
+		//----------------------------------
+
+		/** 
+		 *  @private
+		 *  Returns either the listener or the source
+		 *  for the cardType and cardNumber subfields.
+		 */
+		override protected function get actualListeners():Array
+		{
+			var results:Array = [];
+			
+			var typeResult:Object;
+			if (_cardTypeListener)
+				typeResult = _cardTypeListener;
+			else if (_cardTypeSource)
+				typeResult = _cardTypeSource;
+				
+			results.push(typeResult);
+			if (typeResult is IValidatorListener)
+				IValidatorListener(typeResult).validationSubField = "cardType";
+				
+			var numResult:Object;
+			if (_cardNumberListener)
+				numResult = _cardNumberListener;
+			else if (_cardNumberSource)
+				numResult = _cardNumberSource;
+				
+			results.push(numResult);
+			if (numResult is IValidatorListener)
+				IValidatorListener(numResult).validationSubField = "cardNumber";
+					
+			if (results.length > 0 && listener)
+				results.push(listener);
+
+			return results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  allowedFormatChars
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the allowedFormatChars property.
+		 */
+		private var _allowedFormatChars:String;
+		
+		/**
+		 *  @private
+		 */
+		private var allowedFormatCharsOverride:String;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  The set of formatting characters allowed in the
+		 *  <code>cardNumber</code> field.
+		 *
+		 *  @default " -" (space and dash)
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get allowedFormatChars():String
+		{
+			return _allowedFormatChars;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set allowedFormatChars(value:String):void
+		{
+			if (value != null)
+			{
+				var n:int = value.length;
+				for (var i:int = 0; i < n; i++)
+				{
+					if (DECIMAL_DIGITS.indexOf(value.charAt(i)) != -1)
+					{
+						var message:String = resourceManager.getString(
+							"validators", "invalidFormatChars");
+						throw new Error(message);
+					}
+				}
+			}
+
+			allowedFormatCharsOverride = value;
+
+			_allowedFormatChars = value != null ?
+								value :
+								resourceManager.getString(
+									"validators",
+									"creditCardValidatorAllowedFormatChars");
+		}
+		
+		//----------------------------------
+		//  cardNumberListener
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the cardNumberListener property.
+		 */
+		private var _cardNumberListener:IValidatorListener;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  The component that listens for the validation result
+		 *  for the card number subfield. 
+		 *  If none is specified, use the value specified
+		 *  to the <code>cardNumberSource</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get cardNumberListener():IValidatorListener
+		{
+			return _cardNumberListener;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set cardNumberListener(value:IValidatorListener):void
+		{
+			if (_cardNumberListener == value)
+				return;
+				
+			removeListenerHandler();
+			
+			_cardNumberListener = value;
+			
+			addListenerHandler();
+		}
+			
+		//----------------------------------
+		//  cardNumberProperty
+		//----------------------------------
+
+		[Inspectable(category="General")]
+
+		/**
+		 *  Name of the card number property to validate. 
+		 *  This attribute is optional, but if you specify
+		 *  the <code>cardNumberSource</code> property, 
+		 *  you should also set this property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var cardNumberProperty:String;
+		
+		//----------------------------------
+		//  cardNumberSource
+		//----------------------------------	
+
+		/**
+		 *  @private
+		 *  Storage for the cardNumberSource property.
+		 */
+		private var _cardNumberSource:Object;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  Object that contains the value of the card number field.
+		 *  If you specify a value for this property, you must also specify
+		 *  a value for the <code>cardNumberProperty</code> property. 
+		 *  Do not use this property if you set the <code>source</code> 
+		 *  and <code>property</code> properties. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get cardNumberSource():Object
+		{
+			return _cardNumberSource;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set cardNumberSource(value:Object):void
+		{
+			if (_cardNumberSource == value)
+				return;
+			
+			if (value is String)
+			{
+				var message:String = resourceManager.getString(
+					"validators", "CNSAttribute", [ value ]);
+				throw new Error(message);
+			}
+				
+			removeListenerHandler();	
+			
+			_cardNumberSource = value;
+			
+			addListenerHandler();
+		}
+		
+		//----------------------------------
+		//  cardTypeListener
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the cardTypeListener property.
+		 */
+		private var _cardTypeListener:IValidatorListener;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  The component that listens for the validation result
+		 *  for the card type subfield. 
+		 *  If none is specified, then use the value
+		 *  specified to the <code>cardTypeSource</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get cardTypeListener():IValidatorListener
+		{
+			return _cardTypeListener;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set cardTypeListener(value:IValidatorListener):void
+		{
+			if (_cardTypeListener == value)
+				return;
+				
+			removeListenerHandler();
+			
+			_cardTypeListener = value;
+			
+			addListenerHandler();
+		}
+			
+		//----------------------------------
+		//  cardTypeProperty
+		//----------------------------------
+
+		[Inspectable(category="General")]
+
+		/**
+		 *  Name of the card type property to validate. 
+		 *  This attribute is optional, but if you specify the
+		 *  <code>cardTypeSource</code> property,
+		 *  you should also set this property.
+		 *
+		 *  <p>In MXML, valid values are:</p>
+		 *  <ul>
+		 *    <li><code>"American Express"</code></li>
+		 *    <li><code>"Diners Club"</code></li>
+		 *    <li><code>"Discover"</code></li>
+		 *    <li><code>"MasterCard"</code></li>
+		 *    <li><code>"Visa"</code></li>
+		 *  </ul>
+		 *
+		 *  <p>In ActionScript, you can use the following constants to set this property:</p>
+		 *  <p><code>CreditCardValidatorCardType.AMERICAN_EXPRESS</code>, 
+		 *  <code>CreditCardValidatorCardType.DINERS_CLUB</code>,
+		 *  <code>CreditCardValidatorCardType.DISCOVER</code>, 
+		 *  <code>CreditCardValidatorCardType.MASTER_CARD</code>, and 
+		 *  <code>CreditCardValidatorCardType.VISA</code>.</p>
+		 *
+		 *  @see mx.validators.CreditCardValidatorCardType
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var cardTypeProperty:String;
+		
+		//----------------------------------
+		//  cardTypeSource
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the cardTypeSource property.
+		 */
+		private var _cardTypeSource:Object;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  Object that contains the value of the card type field.
+		 *  If you specify a value for this property, you must also specify
+		 *  a value for the <code>cardTypeProperty</code> property. 
+		 *  Do not use this property if you set the <code>source</code> 
+		 *  and <code>property</code> properties. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get cardTypeSource():Object
+		{
+			return _cardTypeSource;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set cardTypeSource(value:Object):void
+		{
+			if (_cardTypeSource == value)
+				return;
+				
+			if (value is String)
+			{
+				var message:String = resourceManager.getString(
+					"validators", "CTSAttribute", [ value ]);
+				throw new Error(message);
+			}
+				
+			removeListenerHandler();	
+			
+			_cardTypeSource = value;
+			
+			addListenerHandler();
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the <code>cardNumber</code> field contains invalid characters.
+		 *
+		 *  @default "Invalid characters in your credit card number. (Enter numbers only.)"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharErrorCCV");
+		}
+
+		//----------------------------------
+		//  invalidNumberError
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the invalidNumberError property.
+		 */
+		private var _invalidNumberError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidNumberErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+		
+		/** 
+		 *  Error message when the credit card number is invalid.
+		 *
+		 *  @default "The credit card number is invalid."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidNumberError():String
+		{
+			return _invalidNumberError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidNumberError(value:String):void
+		{
+			invalidNumberErrorOverride = value;
+
+			_invalidNumberError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidNumberError");
+		}
+
+		//----------------------------------
+		//  noNumError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the noNumError property.
+		 */
+		private var _noNumError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var noNumErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+		
+		/** 
+		 *  Error message when the <code>cardNumber</code> field is empty.
+		 *
+		 *  @default "No credit card number is specified."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get noNumError():String
+		{
+			return _noNumError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set noNumError(value:String):void
+		{
+			noNumErrorOverride = value;
+
+			_noNumError = value != null ?
+						value :
+						resourceManager.getString(
+							"validators", "noNumError");
+		}
+		
+		//----------------------------------
+		//  noTypeError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the noTypeError property.
+		 */
+		private var _noTypeError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var noTypeErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the <code>cardType</code> field is blank.
+		 *
+		 *  @default "No credit card type is specified or the type is not valid."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get noTypeError():String
+		{
+			return _noTypeError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set noTypeError(value:String):void
+		{
+			noTypeErrorOverride = value;
+
+			_noTypeError = value != null ?
+						value :
+						resourceManager.getString(
+							"validators", "noTypeError");
+		}
+
+		//----------------------------------
+		//  wrongLengthError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongLengthError property.
+		 */
+		private var _wrongLengthError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongLengthErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the <code>cardNumber</code> field contains the wrong
+		 *  number of digits for the specified credit card type.
+		 *
+		 *  @default "Your credit card number contains the wrong number of digits." 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongLengthError():String
+		{
+			return _wrongLengthError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongLengthError(value:String):void
+		{
+			wrongLengthErrorOverride = value;
+
+			_wrongLengthError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "wrongLengthErrorCCV");
+		}
+		
+		//----------------------------------
+		//  wrongTypeError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongTypeError property.
+		 */
+		private var _wrongTypeError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongTypeErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message the <code>cardType</code> field contains an invalid credit card type. 
+		 *  You should use the predefined constants for the <code>cardType</code> field:
+		 *  <code>CreditCardValidatorCardType.MASTER_CARD</code>,
+		 *  <code>CreditCardValidatorCardType.VISA</code>, 
+		 *  <code>CreditCardValidatorCardType.AMERICAN_EXPRESS</code>,
+		 *  <code>CreditCardValidatorCardType.DISCOVER</code>, or 
+		 *  <code>CreditCardValidatorCardType.DINERS_CLUB</code>.
+		 *
+		 *  @default "Incorrect card type is specified."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongTypeError():String
+		{
+			return _wrongTypeError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongTypeError(value:String):void
+		{
+			wrongTypeErrorOverride = value;
+
+			_wrongTypeError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "wrongTypeError");
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private    
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			allowedFormatChars = allowedFormatCharsOverride;
+			
+			invalidCharError = invalidCharErrorOverride;
+			invalidNumberError = invalidNumberErrorOverride;
+			noNumError = noNumErrorOverride;
+			noTypeError = noTypeErrorOverride;
+			wrongLengthError = wrongLengthErrorOverride;
+			wrongTypeError = wrongTypeErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method
+		 *  to validate a credit card number.
+		 *
+		 *  <p>You do not call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom Validator class, you must implement this method. </p>
+		 *
+		 *  @param value an Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+			
+			// Return if there are errors
+			// or if the required property is set to false and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return CreditCardValidator.validateCreditCard(this, value, null);
+		}
+		
+		/**
+		 *  @private
+		 *  Grabs the data for the validator from two different sources
+		 */
+		override protected function getValueFromSource():Object
+		{
+			var useValue:Boolean = false;
+		
+			var value:Object = {};
+			
+			if (cardTypeSource && cardTypeProperty)
+			{
+				value.cardType = cardTypeSource[cardTypeProperty];
+				useValue = true;
+			}
+			
+			if (cardNumberSource && cardNumberProperty)
+			{
+				value.cardNumber = cardNumberSource[cardNumberProperty];
+				useValue = true;
+			}
+		
+			if (useValue)
+				return value;
+			else
+				return super.getValueFromSource();
+		}
+	}
+
+}
+
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidatorCardType.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidatorCardType.as
new file mode 100644
index 0000000..e2e20cd
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CreditCardValidatorCardType.as
@@ -0,0 +1,96 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	/**
+	 *  The CreditCardValidatorCardType class defines value constants
+	 *  for specifying the type of credit card to validate.
+	 *  These values are used in the <code>CreditCardValidator.cardType</code>
+	 *  property.
+	 *
+	 *  @see mx.validators.CreditCardValidator
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public final class CreditCardValidatorCardType
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants 
+		//
+		//--------------------------------------------------------------------------
+			
+		/**
+		 *  Specifies the card type as MasterCard.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const MASTER_CARD:String = "MasterCard"
+		
+		/**
+		 *  Specifies the card type as Visa.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const VISA:String = "Visa";
+		
+		/**
+		 *  Specifies the card type as American Express.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const AMERICAN_EXPRESS:String = "American Express";
+		
+		/**
+		 *  Specifies the card type as Discover.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const DISCOVER:String = "Discover";
+		
+		/**
+		 *  Specifies the card type as Diners Club.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const DINERS_CLUB:String = "Diners Club";
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidator.as
new file mode 100644
index 0000000..5b2b612
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidator.as
@@ -0,0 +1,1299 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+    // [ResourceBundle("SharedResources")]
+    // [ResourceBundle("validators")]
+
+    /**
+     *  The CurrencyValidator class ensures that a String
+     *  represents a valid currency expression.
+     *  It can make sure the input falls within a given range
+     *  (specified by <code>minValue</code> and <code>maxValue</code>),
+     *  is non-negative (specified by <code>allowNegative</code>),
+     *  and does not exceed the specified <code>precision</code>. The 
+     *  CurrencyValidator class correctly validates formatted and unformatted
+     *  currency expressions, e.g., "$12,345.00" and "12345".
+     *  You can customize the <code>currencySymbol</code>, <code>alignSymbol</code>,
+     *  <code>thousandsSeparator</code>, and <code>decimalSeparator</code>
+     *  properties for internationalization.
+     *
+     *  @mxml
+     *
+     *  <p>The <code>&lt;mx:CurrencyValidator&gt;</code> tag
+     *  inherits all of the tag properties of its superclass,
+     *  and adds the following tag properties:</p>
+     *
+     *  <pre>
+     *  &lt;mx:CurrencyValidator
+     *    alignSymbol="left|right|any"
+     *    allowNegative="true|false"
+     *    currencySymbol="$"
+     *    currencySymbolError="The currency symbol occurs in an invalid location."
+     *    decimalPointCountError="The decimal separator can occur only once."
+     *    decimalSeparator="."
+     *    exceedsMaxError="The amount entered is too large."
+     *    invalidCharError="The input contains invalid characters."
+     *    invalidFormatCharsError="One of the formatting parameters is invalid."
+     *    lowerThanMinError="The amount entered is too small."
+     *    maxValue="NaN"
+     *    minValue="NaN"
+     *    negativeError="The amount may not be negative."
+     *    precision="2"
+     *    precisionError="The amount entered has too many digits beyond the decimal point."
+     *    separationError="The thousands separator must be followed by three digits."
+     *    thousandsSeparator=","
+     *  /&gt;
+     *  </pre>
+     *
+     *  @see mx.validators.CurrencyValidatorAlignSymbol
+     *
+     *  @includeExample examples/CurrencyValidatorExample.mxml
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class CurrencyValidator extends Validator
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class constants
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private
+         *  Formatting characters for negative values.
+         */
+        private static const NEGATIVE_FORMATTING_CHARS:String = "-()";
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Convenience method for calling a validator.
+         *  Each of the standard Flex validators has a similar convenience method.
+         *
+         *  @param validator The CurrencyValidator instance.
+         *
+         *  @param value The object to validate.
+         *
+         *  @param baseField Text representation of the subfield
+         *  specified in the <code>value</code> parameter.
+         *  For example, if the <code>value</code> parameter specifies value.currency,
+         *  the baseField value is "currency".
+         *
+         *  @return An Array of ValidationResult objects, with one ValidationResult 
+         *  object for each field examined by the validator. 
+         *
+         *  @see mx.validators.ValidationResult
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public static function validateCurrency(validator:CurrencyValidator,
+                                                value:Object,
+                                                baseField:String):Array
+        {
+            var results:Array = [];
+            
+            // Resource-backed properties of the validator.
+            var alignSymbol:String = validator.alignSymbol;
+            var allowNegative:Boolean = validator.allowNegative;        
+            var currencySymbol:String = validator.currencySymbol;
+            var decimalSeparator:String = validator.decimalSeparator;
+            var maxValue:Number = Number(validator.maxValue);
+            var minValue:Number = Number(validator.minValue);
+            var precision:int = int(validator.precision);
+            var thousandsSeparator:String = validator.thousandsSeparator;
+
+            var input:String = String(value);
+            var len:int = input.length;
+            
+            var isNegative:Boolean = false;
+            
+            var i:int;
+            var c:String;
+
+            // Make sure the formatting character parameters are unique,
+            // are not digits or negative formatting characters,
+            // and that the separators are one character.
+            var invalidFormChars:String = DECIMAL_DIGITS + NEGATIVE_FORMATTING_CHARS;
+
+            if (currencySymbol == thousandsSeparator ||
+                currencySymbol == decimalSeparator ||
+                decimalSeparator == thousandsSeparator ||
+                invalidFormChars.indexOf(currencySymbol) != -1 ||
+                invalidFormChars.indexOf(decimalSeparator) != -1 ||
+                invalidFormChars.indexOf(thousandsSeparator) != -1 ||
+                decimalSeparator.length != 1 ||
+                thousandsSeparator.length != 1)
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "invalidFormatChar",
+                    validator.invalidFormatCharsError));
+                return results;
+            }
+
+            // Check for invalid characters in input.
+            var validChars:String = 
+                DECIMAL_DIGITS + NEGATIVE_FORMATTING_CHARS +
+                currencySymbol + decimalSeparator + thousandsSeparator;
+            for (i = 0; i < len; i++)
+            {
+                c = input.charAt(i);
+
+                if (validChars.indexOf(c) == -1)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidChar",
+                        validator.invalidCharError));
+                    return results;
+                }
+            }
+
+            // Check if the input is negative.
+            if (input.charAt(0) == "-")
+            {
+                // Check if negative input is allowed.
+                if (!allowNegative)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "negative",
+                        validator.negativeError));
+                    return results;
+                }
+
+                // Strip off the negative formatting and update some variables.
+                input = input.substring(1);
+                len--;
+                isNegative = true;
+            }
+
+            else if (input.charAt(0) == "(")
+            {
+                // Make sure the last character is a closed parenthesis.
+                if (input.charAt(len - 1) != ")")
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidChar",
+                        validator.invalidCharError));
+                    return results;
+                }
+
+                // Check if negative input is allowed.
+                if (!allowNegative)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "negative",
+                        validator.negativeError));
+                    return results;
+                }
+
+                // Strip off the negative formatting and update some variables.
+                input = input.substring(1,len-2);
+                len -= 2;
+                isNegative = true;
+            }
+
+            // Find the currency symbol if it exists,
+            // then make sure that it's in the right place
+            // and that there is only one.
+            var currencySymbolLength:uint = currencySymbol.length; // allows for symbols that use multiple chars, like the Brazilian "R$"
+            if ((input.substr(0, currencySymbolLength) == currencySymbol &&
+                alignSymbol == CurrencyValidatorAlignSymbol.RIGHT) ||
+                (input.substr(len - currencySymbolLength, currencySymbolLength) == currencySymbol &&
+                alignSymbol == CurrencyValidatorAlignSymbol.LEFT) ||
+                (len > (2 * currencySymbolLength) &&
+                input.substring(currencySymbolLength, len - currencySymbolLength).indexOf(currencySymbol) != -1) ||
+                (input.indexOf(currencySymbol) !=
+                input.lastIndexOf(currencySymbol)))
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "currencySymbol",
+                    validator.currencySymbolError));
+                return results;
+            }
+
+            // Now that we know it's in the right place,
+            // strip off the currency symbol if it exists.
+            var currencySymbolIndex:int = input.indexOf(currencySymbol);
+            if (currencySymbolIndex != -1)
+            {
+                if (currencySymbolIndex) // if it's at the end
+                    input = input.substring(0, len - currencySymbolLength);
+                else // it's at the beginning
+                    input = input.substring(currencySymbolLength);
+                len -= currencySymbolLength;
+            }
+
+            // Make sure there is only one decimal point.
+            if (input.indexOf(decimalSeparator) !=
+                input.lastIndexOf(decimalSeparator))
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "decimalPointCount",
+                    validator.decimalPointCountError));
+                return results;
+            }
+
+            // Make sure that every character after the decimal point
+            // is a digit and that the precision is not exceeded.
+            var decimalSeparatorIndex:int = input.indexOf(decimalSeparator);
+            var numDigitsAfterDecimal:int = 0;
+
+            // If there is no decimal separator, act like there is one at the end.
+            if (decimalSeparatorIndex == -1)
+            decimalSeparatorIndex = len;
+
+            for (i = decimalSeparatorIndex + 1; i < len; i++)
+            {
+                if (DECIMAL_DIGITS.indexOf(input.charAt(i)) == -1)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidChar",
+                        validator.invalidCharError));
+                    return results;
+                }
+
+                ++numDigitsAfterDecimal;
+
+                // Make sure precision is not exceeded.
+                if (precision != -1 && numDigitsAfterDecimal > precision)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "precision",
+                        validator.precisionError));
+                    return results;
+                }
+            }
+
+            // Make sure the input begins with a digit or a decimal point.
+            if (DECIMAL_DIGITS.indexOf(input.charAt(0)) == -1 &&
+                input.charAt(0) != decimalSeparator)
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "invalidChar",
+                    validator.invalidCharError));
+                return results;
+            }
+
+            // Make sure that every character before the decimal point
+            // is a digit or is a thousands separator.
+            // If it's a thousands separator, make sure it's followed
+            // by three consecutive digits, and then make sure the next character
+            // is valid (i.e., either thousands separator, decimal separator,
+            // or nothing).
+            var validGroupEnder:String = thousandsSeparator + decimalSeparator;
+            for (i = 1; i < decimalSeparatorIndex; i++)
+            {
+                c = input.charAt(i);
+
+                if (c == thousandsSeparator)
+                {
+                    if (input.substring(i + 1, i + 4).length < 3 ||
+                        DECIMAL_DIGITS.indexOf(input.charAt(i + 1)) == -1 ||
+                        DECIMAL_DIGITS.indexOf(input.charAt(i + 2)) == -1 ||
+                        DECIMAL_DIGITS.indexOf(input.charAt(i + 3)) == -1 ||
+                        validGroupEnder.indexOf(input.charAt(i + 4)) == -1)
+                    {
+                        results.push(new ValidationResult(
+                            true, baseField, "separation",
+                            validator.separationError));
+                        return results;
+                    }
+                }
+                else if (DECIMAL_DIGITS.indexOf(c) == -1)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidChar",
+                        validator.invalidCharError));
+                    return results;
+                }
+            }
+
+            // Make sure the input is within the specified range.
+            if (!isNaN(minValue) || !isNaN(maxValue))
+            {
+                // First strip off the thousands separators.
+                for (i = 0; i < decimalSeparatorIndex; i++)
+                {
+                    if (input.charAt(i) == thousandsSeparator)
+                    {
+                        var left:String = input.substring(0, i);
+                        var right:String = input.substring(i + 1);
+                        input = left + right;
+                    }
+                }
+                
+                // Translate the value back into standard english
+                // If the decimalSeperator is not '.' we need to change it to '.' 
+                // so that the number casting will work properly
+                if (validator.decimalSeparator != '.')
+                {
+                    var dIndex:int = input.indexOf( validator.decimalSeparator );
+                    if (dIndex != -1)
+                    { 
+                        var dLeft:String = input.substring(0, dIndex);
+                        var dRight:String = input.substring(dIndex + 1);
+                        input = dLeft + '.' + dRight;
+                    }
+                }
+
+                // Check bounds
+
+                var x:Number = Number(input);
+
+                if (isNegative)
+                    x = -x;
+
+                if (!isNaN(minValue) && x < minValue)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "lowerThanMin",
+                        validator.lowerThanMinError));
+                    return results;
+                }
+
+                if (!isNaN(maxValue) && x > maxValue)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "exceedsMax",
+                        validator.exceedsMaxError));
+                    return results;
+                }
+            }
+
+            return results;
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Constructor.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function CurrencyValidator()
+        {
+            super();
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  alignSymbol
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the alignSymbol property.
+         */
+        private var _alignSymbol:String;
+        
+        /**
+         *  @private
+         */
+        private var alignSymbolOverride:String;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  Specifies the alignment of the <code>currencySymbol</code>
+         *  relative to the rest of the expression.
+         *  Acceptable values in ActionScript are <code>CurrencyValidatorAlignSymbol.LEFT</code>, 
+         *  <code>CurrencyValidatorAlignSymbol.RIGHT</code>, and 
+         *  <code>CurrencyValidatorAlignSymbol.ANY</code>.
+         *  Acceptable values in MXML are <code>"left"</code>, 
+         *  <code>"right"</code>, and 
+         *  <code>"any"</code>.
+         * 
+         *  @default CurrencyValidatorAlignSymbol.LEFT
+         *
+         *  @see mx.validators.CurrencyValidatorAlignSymbol
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get alignSymbol():String
+        {
+            return _alignSymbol;
+        }
+
+        /**
+         *  @private
+         */
+        public function set alignSymbol(value:String):void
+        {
+            alignSymbolOverride = value;
+
+            _alignSymbol = value != null ?
+                        value :
+                        resourceManager.getString(
+                            "SharedResources", "alignSymbol");
+        }
+
+        //----------------------------------
+        //  allowNegative
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the allowNegative property.
+         */
+        private var _allowNegative:Object;
+        
+        /**
+         *  @private
+         */
+        private var allowNegativeOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  Specifies whether negative numbers are permitted.
+         *  Can be <code>true</code> or <code>false</code>.
+         *  
+         *  @default true
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get allowNegative():Object
+        {
+            return _allowNegative;
+        }
+
+        /**
+         *  @private
+         */
+        public function set allowNegative(value:Object):void
+        {
+            allowNegativeOverride = value;
+
+            _allowNegative = value != null ?
+                            Boolean(value) : false;
+            //TODO get the value based on locale
+            // _allowNegative = value != null ?
+            //                 Boolean(value) :
+            //                 resourceManager.getBoolean(
+            //                     "validators", "allowNegative");
+        }
+
+        //----------------------------------
+        //  currencySymbol
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the currencySymbol property.
+         */
+        private var _currencySymbol:String;
+        
+        /**
+         *  @private
+         */
+        private var currencySymbolOverride:String;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  The character String used to specify the currency symbol, 
+         *  such as "$", "R$", or "&#163;".
+         *  Cannot be a digit and must be distinct from the
+         *  <code>thousandsSeparator</code> and the <code>decimalSeparator</code>.
+         *
+         *  @default "$"
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get currencySymbol():String
+        {
+            return _currencySymbol;
+        }
+
+        /**
+         *  @private
+         */
+        public function set currencySymbol(value:String):void
+        {
+            currencySymbolOverride = value;
+
+            _currencySymbol = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "SharedResources", "currencySymbol");
+        }
+
+        //----------------------------------
+        //  decimalSeparator
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the decimalSeparator property.
+         */
+        private var _decimalSeparator:String;
+        
+        /**
+         *  @private
+         */
+        private var decimalSeparatorOverride:String;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  The character used to separate the whole
+         *  from the fractional part of the number.
+         *  Cannot be a digit and must be distinct from the
+         *  <code>currencySymbol</code> and the <code>thousandsSeparator</code>.
+         *  
+         *  @default "."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */ 
+        public function get decimalSeparator():String
+        {
+            return _decimalSeparator;
+        }
+
+        /**
+         *  @private
+         */
+        public function set decimalSeparator(value:String):void
+        {
+            decimalSeparatorOverride = value;
+
+            _decimalSeparator = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "decimalSeparator");
+        }
+
+        //----------------------------------
+        //  maxValue
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the maxValue property.
+         */
+        private var _maxValue:Object;
+        
+        /**
+         *  @private
+         */
+        private var maxValueOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  Maximum value for a valid number.
+         *  A value of NaN means it is ignored.
+         *  
+         *  @default NaN
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get maxValue():Object
+        {
+            return _maxValue;
+        }
+
+        /**
+         *  @private
+         */
+        public function set maxValue(value:Object):void
+        {
+            maxValueOverride = value;
+
+            _maxValue = value != null ?
+                        Number(value) : Number.MAX_VALUE;
+            // TODO get from resource bundle
+            // _maxValue = value != null ?
+            //             Number(value) :
+            //             resourceManager.getNumber(
+            //                 "validators", "maxValue");
+        }
+
+        //----------------------------------
+        //  minValue
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the minValue property.
+         */
+        private var _minValue:Object;
+        
+        /**
+         *  @private
+         */
+        private var minValueOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  Minimum value for a valid number.
+         *  A value of NaN means it is ignored.
+         *  
+         *  @default NaN
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get minValue():Object
+        {
+            return _minValue;
+        }
+
+        /**
+         *  @private
+         */
+        public function set minValue(value:Object):void
+        {
+            minValueOverride = value;
+
+            _minValue = value != null ?
+                        Number(value) : Number.MIN_VALUE;
+            // TODO get from resource bundle
+            // _minValue = value != null ?
+            //             Number(value) :
+            //             resourceManager.getNumber(
+            //                 "validators", "minValue");
+        }
+
+        //----------------------------------
+        //  precision
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the precision property.
+         */
+        private var _precision:Object;
+        
+        /**
+         *  @private
+         */
+        private var precisionOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  The maximum number of digits allowed to follow the decimal point.
+         *  Can be any non-negative integer.
+         *  Note: Setting to <code>0</code>
+         *  has the same effect as setting <code>NumberValidator.domain</code>
+         *  to <code>int</code>.
+         *  Setting it to -1, means it is ignored.
+         * 
+         *  @default 2
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get precision():Object
+        {
+            return _precision;
+        }
+
+        /**
+         *  @private
+         */
+        public function set precision(value:Object):void
+        {
+            precisionOverride = value;
+
+            _precision = value != null ?
+                        int(value) : 2;
+            // TODO get from resource bundle
+            // _precision = value != null ?
+            //             int(value) :
+            //             resourceManager.getInt(
+            //                 "validators", "currencyValidatorPrecision");
+        }
+
+        //----------------------------------
+        //  thousandsSeparator
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the thousandsSeparator property.
+         */
+        private var _thousandsSeparator:String;
+        
+        /**
+         *  @private
+         */
+        private var thousandsSeparatorOverride:String;
+        
+        [Inspectable(category="General", defaultValue=",")]
+
+        /**
+         *  The character used to separate thousands.
+         *  Cannot be a digit and must be distinct from the
+         *  <code>currencySymbol</code> and the <code>decimalSeparator</code>.
+         *  
+         *  @default ","
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get thousandsSeparator():String
+        {
+            return _thousandsSeparator;
+        }
+
+        /**
+         *  @private
+         */
+        public function set thousandsSeparator(value:String):void
+        {
+            thousandsSeparatorOverride = value;
+
+            _thousandsSeparator = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "thousandsSeparator");
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties: Errors
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  currencySymbolError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the currencySymbolError property.
+         */
+        private var _currencySymbolError:String;
+        
+        /**
+         *  @private
+         */
+        private var currencySymbolErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the currency symbol, defined by <code>currencySymbol</code>,
+         *  is in the wrong location.
+         *  
+         *  @default "The currency symbol occurs in an invalid location."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get currencySymbolError():String
+        {
+            return _currencySymbolError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set currencySymbolError(value:String):void
+        {
+            currencySymbolErrorOverride = value;
+
+            _currencySymbolError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "currencySymbolError");
+        }
+
+        //----------------------------------
+        //  decimalPointCountError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the decimalPointCountError property.
+         */
+        private var _decimalPointCountError:String;
+        
+        /**
+         *  @private
+         */
+        private var decimalPointCountErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the decimal separator character occurs more than once.
+         *  
+         *  @default "The decimal separator can only occur once."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get decimalPointCountError():String
+        {
+            return _decimalPointCountError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set decimalPointCountError(value:String):void
+        {
+            decimalPointCountErrorOverride = value;
+
+            _decimalPointCountError = value != null ?
+                                    value :
+                                    resourceManager.getString(
+                                        "validators", "decimalPointCountError");
+        }
+
+        //----------------------------------
+        //  exceedsMaxError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the exceedsMaxError property.
+         */
+        private var _exceedsMaxError:String;
+        
+        /**
+         *  @private
+         */
+        private var exceedsMaxErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the value is greater than <code>maxValue</code>.
+         *  
+         *  @default "The amount entered is too large."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get exceedsMaxError():String
+        {
+            return _exceedsMaxError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set exceedsMaxError(value:String):void
+        {
+            exceedsMaxErrorOverride = value;
+
+            _exceedsMaxError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "exceedsMaxErrorCV");
+        }
+
+        //----------------------------------
+        //  invalidCharError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the invalidCharError property.
+         */
+        private var _invalidCharError:String;
+        
+        /**
+         *  @private
+         */
+        private var invalidCharErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the currency contains invalid characters.
+         *  
+         *  @default "The input contains invalid characters."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */ 
+        public function get invalidCharError():String
+        {
+            return _invalidCharError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set invalidCharError(value:String):void
+        {
+            invalidCharErrorOverride = value;
+
+            _invalidCharError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "invalidCharError");
+        }
+
+        //----------------------------------
+        //  invalidFormatCharsError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the invalidFormatCharsError property.
+         */
+        private var _invalidFormatCharsError:String;
+        
+        /**
+         *  @private
+         */
+        private var invalidFormatCharsErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the value contains an invalid formatting character.
+         *  
+         *  @default "One of the formatting parameters is invalid."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get invalidFormatCharsError():String
+        {
+            return _invalidFormatCharsError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set invalidFormatCharsError(value:String):void
+        {
+            invalidFormatCharsErrorOverride = value;
+
+            _invalidFormatCharsError = value != null ?
+                                    value :
+                                    resourceManager.getString(
+                                        "validators", "invalidFormatCharsError");
+        }
+
+        //----------------------------------
+        //  lowerThanMinError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the lowerThanMinError property.
+         */
+        private var _lowerThanMinError:String;
+        
+        /**
+         *  @private
+         */
+        private var lowerThanMinErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the value is less than <code>minValue</code>.
+         *  
+         *  @default "The amount entered is too small."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get lowerThanMinError():String
+        {
+            return _lowerThanMinError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set lowerThanMinError(value:String):void
+        {
+            lowerThanMinErrorOverride = value;
+
+            _lowerThanMinError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "lowerThanMinError");
+        }
+
+        //----------------------------------
+        //  negativeError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the negativeError property.
+         */
+        private var _negativeError:String;
+        
+        /**
+         *  @private
+         */
+        private var negativeErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the value is negative and
+         *  the <code>allowNegative</code> property is <code>false</code>.
+         *  
+         *  @default "The amount may not be negative."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get negativeError():String
+        {
+            return _negativeError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set negativeError(value:String):void
+        {
+            negativeErrorOverride = value;
+
+            _negativeError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "negativeError");
+        }
+
+        //----------------------------------
+        //  precisionError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the precisionError property.
+         */
+        private var _precisionError:String;
+        
+        /**
+         *  @private
+         */
+        private var precisionErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the value has a precision that exceeds the value
+         *  defined by the <code>precision</code> property.
+         *  
+         *  @default "The amount entered has too many digits beyond 
+         *  the decimal point."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get precisionError():String
+        {
+            return _precisionError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set precisionError(value:String):void
+        {
+            precisionErrorOverride = value;
+
+            _precisionError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "precisionError");
+        }
+
+        //----------------------------------
+        //  separationError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the separationError property.
+         */
+        private var _separationError:String;
+        
+        /**
+         *  @private
+         */
+        private var separationErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /**
+         *  Error message when the thousands separator is incorrectly placed.
+         *  
+         *  @default "The thousands separator must be followed by three digits."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get separationError():String
+        {
+            return _separationError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set separationError(value:String):void
+        {
+            separationErrorOverride = value;
+
+            _separationError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "separationError");
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Overridden methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private    
+         */
+        override protected function resourcesChanged():void
+        {
+            super.resourcesChanged();
+
+            alignSymbol = alignSymbolOverride;
+            allowNegative = allowNegativeOverride;      
+            currencySymbol = currencySymbolOverride;
+            decimalSeparator = decimalSeparatorOverride;
+            maxValue = maxValueOverride;
+            minValue = minValueOverride;
+            precision = precisionOverride;
+            thousandsSeparator = thousandsSeparatorOverride;
+            
+            currencySymbolError = currencySymbolErrorOverride;
+            decimalPointCountError = decimalPointCountErrorOverride;
+            exceedsMaxError = exceedsMaxErrorOverride;
+            invalidCharError = invalidCharErrorOverride;
+            invalidFormatCharsError = invalidFormatCharsErrorOverride;
+            lowerThanMinError = lowerThanMinErrorOverride;
+            negativeError = negativeErrorOverride;
+            precisionError = precisionErrorOverride;
+            separationError = separationErrorOverride;
+        }
+
+        /**
+         *  Override of the base class <code>doValidation()</code> method
+         *  to validate a currency expression.
+         *
+         *  <p>You do not call this method directly;
+         *  Flex calls it as part of performing a validation.
+         *  If you create a custom Validator class, you must implement this method. </p>
+         *
+         *  @param value Object to validate.
+         *
+         *  @return An Array of ValidationResult objects, with one ValidationResult 
+         *  object for each field examined by the validator. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        override protected function doValidation(value:Object):Array
+        {
+            var results:Array = super.doValidation(value);
+            
+            // Return if there are errors
+            // or if the required property is set to false and length is 0.
+            var val:String = value ? String(value) : "";
+            if (results.length > 0 || ((val.length == 0) && !required))
+                return results;
+            else
+                return CurrencyValidator.validateCurrency(this, value, null);
+        }
+    }
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidatorAlignSymbol.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidatorAlignSymbol.as
new file mode 100644
index 0000000..4af9f38
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/CurrencyValidatorAlignSymbol.as
@@ -0,0 +1,79 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	/**
+	 *  The CurrencyValidatorAlignSymbol class defines value constants
+	 *  for specifying currency symbol alignment.
+	 *  These values are used in the <code>CurrencyValidator.alignSymbol</code>
+	 *  property.
+	 *
+	 *  @see mx.validators.CurrencyValidator
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public final class CurrencyValidatorAlignSymbol
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Specifies <code>"any"</code> as the alignment of the currency symbol
+		 *  for the CurrencyValidator class.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const ANY:String = "any";
+
+		/**
+		 *  Specifies <code>"left"</code> as the alignment of the currency symbol
+		 *  for the CurrencyValidator class.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const LEFT:String = "left";
+
+		/**
+		 *  Specifies <code>"right"</code> as the alignment of the currency symbol
+		 *  for the CurrencyValidator class.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const RIGHT:String = "right";
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/DateValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/DateValidator.as
new file mode 100644
index 0000000..b4ff45a
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/DateValidator.as
@@ -0,0 +1,1446 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	// [ResourceBundle("SharedResources")]
+	// [ResourceBundle("validators")]
+
+	/**
+	 *  The DateValidator class validates that a String, Date, or Object contains a 
+	 *  proper date and matches a specified format. Users can enter a single 
+	 *  digit or two digits for month, day, and year. 
+	 *  By default, the validator ensures the following formats:
+	 *
+	 *  <ul>
+	 *    <li>The month is between 1 and 12 (or 0-11 for <code>Date</code> objects)</li>
+	 *    <li>The day is between 1 and 31</li>
+	 *    <li>The year is a number</li>
+	 *  </ul>
+	 *
+	 *  <p>You can specify the date in the DateValidator class in two ways:</p>
+	 *  <ul>
+	 *    <li>Single String containing the date - Use the <code>source</code>
+	 *    and <code>property</code> properties to specify the String.
+	 *    The String can contain digits and the formatting characters
+	 *    specified by the <code>allowedFormatChars</code> property,
+	 *    which include the "/\-. " characters. 
+	 *    By default, the input format of the date in a String field
+	 *    is "MM/DD/YYYY" where "MM" is the month, "DD" is the day,
+	 *    and "YYYY" is the year. 
+	 *    You can use the <code>inputFormat</code> property
+	 *    to specify a different format.</li>
+	 * 	  <li><code>Date</code> object.</li>
+	 *    <li>Object or multiple fields containing the day, month, and year.  
+	 *    Use all of the following properties to specify the day, month,
+	 *    and year inputs: <code>daySource</code>, <code>dayProperty</code>,
+	 *    <code>monthSource</code>, <code>monthProperty</code>,
+	 *    <code>yearSource</code>, and <code>yearProperty</code>.</li>
+	 *  </ul>
+	 *  
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:DateValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>  
+	 *  
+	 *  <pre>
+	 *  &lt;mx:DateValidator 
+	 *    allowedFormatChars="/\-. " 
+	 *    dayListener="<i>Object specified by daySource</i>"
+	 *    dayProperty="<i>No default</i>"
+	 *    daySource="<i>No default</i>"
+	 *    formatError= "Configuration error: Incorrect formatting string." 
+	 *    inputFormat="MM/DD/YYYY" 
+	 *    invalidCharError="The date contains invalid characters."
+	 *    monthListener="<i>Object specified by monthSource</i>"
+	 *    monthProperty="<i>No default</i>"
+	 *    monthSource="<i>No default</i>"
+	 *    validateAsString="true|false"
+	 *    wrongDayError="Enter a valid day for the month."
+	 *    wrongLengthError="Type the date in the format <i>inputFormat</i>." 
+	 *    wrongMonthError="Enter a month between 1 and 12."
+	 *    wrongYearError="Enter a year between 0 and 9999."
+	 *    yearListener="<i>Object specified by yearSource</i>"
+	 *    yearProperty="<i>No default</i>"
+	 *    yearSource="<i>No default</i>"
+	 *  /&gt;
+	 *  </pre>
+	 *  
+	 *  @includeExample examples/DateValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class DateValidator extends Validator
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Convenience method for calling a validator
+		 *  from within a custom validation function.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The DateValidator instance.
+		 *
+		 *  @param value A field to validate.
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the value parameter. 
+		 *  For example, if the <code>value</code> parameter
+		 *  specifies value.date, the <code>baseField</code> value is "date".
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validateDate(validator:DateValidator,
+											value:Object,
+											baseField:String):Array
+		{
+			var results:Array = [];
+		
+			// Resource-backed properties of the validator.
+			var allowedFormatChars:String = validator.allowedFormatChars;
+			var inputFormat:String = validator.inputFormat;
+			var validateAsString:Boolean = validator.validateAsString;
+
+			var resourceManager:IResourceManager = ResourceManager.getInstance();
+
+			var validInput:String = DECIMAL_DIGITS + allowedFormatChars;
+			
+			var dateObj:Object = {};
+			dateObj.month = "";
+			dateObj.day = "";
+			dateObj.year = "";
+			
+			var dayProp:String = baseField;
+			var yearProp:String = baseField;
+			var monthProp:String = baseField;
+
+			var advanceValueCounter:Boolean = true;
+			var monthRequired:Boolean = false;
+			var dayRequired:Boolean = false
+			var yearRequired:Boolean = false;
+			var valueIsString:Boolean = false;
+			var foundMonth:Boolean = false;
+			var foundYear:Boolean = false;
+			
+			var objValue:Object;
+			var stringValue:Object;
+		
+			var n:int;
+			var i:int;
+			var temp:String;
+			
+			n = allowedFormatChars.length;
+			for (i = 0; i < n; i++)
+			{
+				if (DECIMAL_DIGITS.indexOf(allowedFormatChars.charAt(i)) != -1)
+				{
+					var message:String = resourceManager.getString(
+						"validators", "invalidFormatChars");
+					throw new Error(message);
+				}
+			}
+			
+			if (value is String)
+			{
+				valueIsString = true;
+				stringValue = String(value);
+			}
+			else if (value is Number)
+			{
+				valueIsString = true;
+				stringValue = String(value);
+			}
+			else if (value is Date)
+			{
+				var date:Date = value as Date;
+				objValue = {year: date.getFullYear(),
+							month: date.getMonth() + 1,
+							day: date.getDate()};
+			}
+			else
+			{
+				objValue = value;
+			}
+
+			// Check if the validator is an object or a string.
+			if (!validateAsString || !valueIsString)
+			{
+				var baseFieldDot:String = baseField ? baseField + "." : "";
+				dayProp = baseFieldDot + "day";
+				yearProp = baseFieldDot + "year";
+				monthProp = baseFieldDot + "month";
+				
+				if (validator.required && (!objValue.month || objValue.month == ""))
+				{
+					results.push(new ValidationResult(
+						true, monthProp,"requiredField",
+						validator.requiredFieldError));
+				}
+				else if (isNaN(objValue.month))
+				{
+					results.push(new ValidationResult(
+						true, monthProp, "wrongMonth",
+						validator.wrongMonthError));
+				}
+				else
+				{
+					monthRequired = true;
+				}
+				
+				if (validator.required && (!objValue.year || objValue.year == ""))
+				{
+					results.push(new ValidationResult(
+						true, yearProp, "requiredField",
+						validator.requiredFieldError));
+				}
+				else if (isNaN(objValue.year))
+				{
+					results.push(new ValidationResult(
+						true, yearProp, "wrongYear",
+						validator.wrongYearError));
+				}
+				else
+				{
+					yearRequired = true;
+				}
+				
+				var dayMissing:Boolean = (!objValue.day || objValue.day == "");
+				var dayInvalid:Boolean = dayMissing || isNaN(objValue.day);
+				var dayWrong:Boolean = !dayMissing && isNaN(objValue.day);
+				var dayOptional:Boolean = yearRequired && monthRequired;			
+				
+				// If the validator is required and there is no day specified			
+				if (validator.required && dayMissing)
+				{
+					results.push(new ValidationResult(
+						true, dayProp, "requiredField",
+						validator.requiredFieldError));
+				}
+				else if (!dayInvalid) // The day is valid (a number).
+				{
+					dayRequired = true;
+				}
+				else if (!dayOptional || dayWrong) // Day is not optional and is NaN.
+				{
+					results.push(new ValidationResult(
+						true, dayProp, "wrongDay",
+						validator.wrongDayError));
+				}
+
+				dateObj.month = objValue.month ? String(objValue.month) : "";
+				dateObj.day = objValue.day ? String(objValue.day) : "";
+				dateObj.year = objValue.year ? String(objValue.year) : "";
+			}
+			else
+			{
+				var result:ValidationResult = DateValidator.validateFormatString(
+					validator, inputFormat, baseField);
+				if (result != null)
+				{
+					results.push(result);
+					return results;
+				}
+				else
+				{
+					var len:Number = stringValue.length;
+					if (len > inputFormat.length ||
+						len + 2 < inputFormat.length)
+					{
+						results.push(new ValidationResult(
+							true, baseField, "wrongLength",
+							validator.wrongLengthError + " " + inputFormat));
+						return results;
+					}
+	
+					var j:int = 0;
+					n = inputFormat.length;
+					for (i = 0; i < n; i++)
+					{
+						temp = "" + stringValue.substring(j, j + 1);
+						var mask:String = "" + inputFormat.substring(i, i + 1);
+						
+						// Check each character to see if it is allowed.
+						if (validInput.indexOf(temp) == -1)
+						{
+							results.push(new ValidationResult(
+								true, baseField, "invalidChar",
+								validator.invalidCharError));
+							return results;
+						}
+						if (mask == "m" || mask == "M")
+						{
+							monthRequired = true;
+							if (isNaN(Number(temp)))
+								advanceValueCounter = false;
+							else
+								dateObj.month += temp;
+						}
+						else if (mask == "d" || mask == "D")
+						{
+							dayRequired = true;
+							if (isNaN(Number(temp)))
+								advanceValueCounter = false;
+							else
+								dateObj.day += temp;
+						}
+						else if (mask == "y" || mask == "Y")
+						{
+							yearRequired = true;
+							if (isNaN(Number(temp)))
+							{
+								results.push(new ValidationResult(
+									true, baseField, "wrongLength", 
+									validator.wrongLengthError + " " +
+									inputFormat));
+								return results;
+							}
+							else
+							{
+								dateObj.year += temp;
+							}
+						}
+						else if (allowedFormatChars.indexOf(temp) == -1)
+						{
+							results.push(new ValidationResult(
+								true, baseField, "invalidChar", 
+								validator.invalidCharError));
+							return results;
+						}
+						
+						if (advanceValueCounter)
+							j++;
+						advanceValueCounter = true;	
+					}
+					
+					if ((monthRequired && dateObj.month == "") ||
+						(dayRequired && dateObj.day == "") ||
+						(yearRequired && dateObj.year == "") ||
+						(j != len))
+					{
+						results.push(new ValidationResult(
+							true, baseField, "wrongLength", 
+							validator.wrongLengthError + " " +
+							inputFormat));
+						return results;
+					}
+				}
+			}
+
+			// Now, validate the sub-elements, which may have been set directly.
+			n = dateObj.month.length;
+			for (i = 0; i < n; i++)
+			{
+				temp = "" + dateObj.month.substring(i, i + 1);
+				if (DECIMAL_DIGITS.indexOf(temp) == -1)
+				{
+					results.push(new ValidationResult(
+						true, monthProp, "invalidChar",
+						validator.invalidCharError));
+				}
+			}
+			n = dateObj.day.length;
+			for (i = 0; i < n; i++)
+			{
+				temp = "" + dateObj.day.substring(i, i + 1);
+				if (DECIMAL_DIGITS.indexOf(temp) == -1)
+				{
+					results.push(new ValidationResult(
+						true, dayProp, "invalidChar",
+						validator.invalidCharError));
+				}
+			}
+			n = dateObj.year.length;
+			for (i = 0; i < n; i++)
+			{
+				temp = "" + dateObj.year.substring(i, i + 1);
+				if (DECIMAL_DIGITS.indexOf(temp) == -1)
+				{
+					results.push(new ValidationResult(
+						true, yearProp, "invalidChar",
+						validator.invalidCharError));
+				}
+			}
+
+			if (results.length > 0)
+				return results;
+			
+			var monthNum:Number = Number(dateObj.month);
+			var dayNum:Number = Number(dateObj.day);
+			var yearNum:Number = Number(dateObj.year).valueOf();
+
+			if (monthNum > 12 || monthNum < 1)
+			{
+				results.push(new ValidationResult(
+					true, monthProp, "wrongMonth",
+					validator.wrongMonthError));
+				return results;
+			}
+
+			var maxDay:Number = 31;
+
+			if (monthNum == 4 || monthNum == 6 ||
+				monthNum == 9 || monthNum == 11)
+			{
+				maxDay = 30;
+			}
+			else if (monthNum == 2)
+			{
+				if (yearNum % 4 > 0)
+					maxDay = 28;
+				else if (yearNum % 100 == 0 && yearNum % 400 > 0)
+					maxDay = 28;
+				else
+					maxDay = 29;
+			}
+
+			if (dayRequired && (dayNum > maxDay || dayNum < 1))
+			{
+				results.push(new ValidationResult(
+					true, dayProp, "wrongDay",
+					validator.wrongDayError));
+				return results;
+			}
+
+			if (yearRequired && (yearNum > 9999 || yearNum < 0))
+			{
+				results.push(new ValidationResult(
+					true, yearProp, "wrongYear",
+					validator.wrongYearError));
+				return results;
+			}
+
+			return results;
+		}
+
+		/**
+		 *  @private
+		 */
+		private static function validateFormatString(
+									validator:DateValidator,
+									format:String,
+									baseField:String):ValidationResult
+		{
+			var monthCounter:Number = 0;
+			var dayCounter:Number = 0;
+			var yearCounter:Number = 0;
+			
+			var n:int = format.length;
+			for (var i:int = 0; i < n; i++)
+			{
+				var mask:String = "" + format.substring(i, i + 1);
+				
+				// Check for upper and lower case to maintain backwards compatibility.
+				if (mask == "m" || mask == "M")
+					monthCounter++;
+				else if (mask == "d" || mask == "D")
+					dayCounter++;
+				else if (mask == "y" || mask == "Y")
+					yearCounter++;
+			}
+
+			if ((monthCounter == 2 &&
+				(yearCounter == 2 || yearCounter == 4)) ||
+				(monthCounter == 2 && dayCounter == 2 &&
+				(yearCounter == 0 || yearCounter == 2 || yearCounter == 4)))
+			{
+				return null; // Passes format validation
+			}
+			else
+			{
+				return new ValidationResult(
+					true, baseField, "format",
+					validator.formatError);
+			}
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function DateValidator()
+		{
+			super();
+			
+			subFields = [ "day", "month", "year" ];
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  actualListeners
+		//----------------------------------
+
+		/** 
+		 *  @private
+		 *  Returns either the listener or the source
+		 *  for the day, month and year subfields.
+		 */
+		override protected function get actualListeners():Array
+		{
+			var results:Array = [];
+		
+			var dayResult:Object;
+			if (_dayListener)
+				dayResult = _dayListener;
+			else if (_daySource)
+				dayResult = _daySource;
+				
+			if (dayResult)
+			{
+				results.push(dayResult);
+				if (dayResult is IValidatorListener)
+					IValidatorListener(dayResult).validationSubField = "day";
+			}
+			
+			var monthResult:Object;
+			if (_monthListener)
+				monthResult = _monthListener;
+			else if (_monthSource)
+				monthResult = _monthSource;
+				
+			if (monthResult)
+			{
+				results.push(monthResult);
+				if (monthResult is IValidatorListener)
+					IValidatorListener(monthResult).validationSubField = "month";
+			}
+			
+			var yearResult:Object;
+			if (_yearListener)
+				yearResult = _yearListener;
+			else if (_yearSource)
+				yearResult = _yearSource;
+				
+			if (yearResult)
+			{
+				results.push(yearResult);
+				if (yearResult is IValidatorListener)
+					IValidatorListener(yearResult).validationSubField = "year";
+			}
+			
+			if (results.length > 0 && listener)
+				results.push(listener);
+			else
+				results = results.concat(super.actualListeners);
+			
+			return results;
+		}	
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  allowedFormatChars
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the allowedFormatChars property.
+		 */
+		private var _allowedFormatChars:String;
+
+		/**
+		 *  @private
+		 */
+		private var allowedFormatCharsOverride:String;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  The set of formatting characters allowed for separating
+		 *  the month, day, and year values.
+		 *
+		 *  @default "/\-. "
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get allowedFormatChars():String
+		{
+			return _allowedFormatChars;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set allowedFormatChars(value:String):void
+		{	
+			if (value != null)
+			{
+				var n:int = value.length;
+				for (var i:int = 0; i < n; i++)
+				{
+					if (DECIMAL_DIGITS.indexOf(value.charAt(i)) != -1)
+					{
+						var message:String = resourceManager.getString(
+							"validators", "invalidFormatChars");
+						throw new Error(message);
+					}
+				}
+			}
+
+			allowedFormatCharsOverride = value;
+
+			_allowedFormatChars = value != null ?
+								value :
+								resourceManager.getString(
+									"validators",
+									"dateValidatorAllowedFormatChars");
+		}
+
+		//----------------------------------
+		//  dayListener
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the dayListener property.
+		 */
+		private var _dayListener:IValidatorListener;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  The component that listens for the validation result
+		 *  for the day subfield.
+		 *  If none is specified, use the value specified
+		 *  for the <code>daySource</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get dayListener():IValidatorListener
+		{
+			return _dayListener;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set dayListener(value:IValidatorListener):void
+		{
+			if (_dayListener == value)
+				return;
+				
+			removeListenerHandler();	
+				
+			_dayListener = value;
+			
+			addListenerHandler();
+		}
+		
+		//----------------------------------
+		//  dayProperty
+		//----------------------------------
+		
+		[Inspectable(category="General")]
+		
+		/**
+		 *  Name of the day property to validate. 
+		 *  This property is optional, but if you specify the
+		 *  <code>daySource</code> property, you should also set this property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var dayProperty:String;
+		
+		//----------------------------------
+		//  daySource
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the daySource property.
+		 */
+		private var _daySource:Object;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  Object that contains the value of the day field.
+		 *  If you specify a value for this property, you must also
+		 *  specify a value for the <code>dayProperty</code> property. 
+		 *  Do not use this property if you set the <code>source</code> 
+		 *  and <code>property</code> properties. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get daySource():Object
+		{
+			return _daySource;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set daySource(value:Object):void
+		{
+			if (_daySource == value)
+				return;
+			
+			if (value is String)
+			{
+				var message:String = resourceManager.getString(
+					"validators", "DSAttribute", [ value ]);
+				throw new Error(message);
+			}
+				
+			removeListenerHandler();	
+				
+			_daySource = value;
+			
+			addListenerHandler();
+		}
+		
+		//----------------------------------
+		//  inputFormat
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the inputFormat property.
+		 */
+		private var _inputFormat:String;
+		
+		/**
+		 *  @private
+		 */
+		private var inputFormatOverride:String;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  The date format to validate the value against.
+		 *  "MM" is the month, "DD" is the day, and "YYYY" is the year.
+		 *  This String is case-sensitive.
+		 *
+		 *  @default "MM/DD/YYYY"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get inputFormat():String
+		{
+			return _inputFormat;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set inputFormat(value:String):void
+		{
+			inputFormatOverride = value;
+
+			_inputFormat = value != null ?
+						value :
+						resourceManager.getString(
+							"SharedResources", "dateFormat");
+		}
+
+		//----------------------------------
+		//  monthListener
+		//----------------------------------		
+		
+		/**
+		 *  @private
+		 *  Storage for the monthListener property.
+		 */
+		private var _monthListener:IValidatorListener; 
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  The component that listens for the validation result
+		 *  for the month subfield. 
+		 *  If none is specified, use the value specified
+		 *  for the <code>monthSource</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get monthListener():IValidatorListener
+		{
+			return _monthListener;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set monthListener(value:IValidatorListener):void
+		{
+			if (_monthListener == value)
+				return;
+				
+			removeListenerHandler();	
+				
+			_monthListener = value;
+			
+			addListenerHandler();
+		}
+		
+		//----------------------------------
+		//  monthProperty
+		//----------------------------------	
+
+		[Inspectable(category="General")]
+
+		/**
+		 *  Name of the month property to validate. 
+		 *  This property is optional, but if you specify the
+		 *  <code>monthSource</code> property, you should also set this property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var monthProperty:String;
+			
+		//----------------------------------
+		//  monthSource
+		//----------------------------------	
+		
+		/**
+		 *  @private
+		 *  Storage for the monthSource property.
+		 */
+		private var _monthSource:Object;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  Object that contains the value of the month field.
+		 *  If you specify a value for this property, you must also specify
+		 *  a value for the <code>monthProperty</code> property. 
+		 *  Do not use this property if you set the <code>source</code> 
+		 *  and <code>property</code> properties. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get monthSource():Object
+		{
+			return _monthSource;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set monthSource(value:Object):void
+		{
+			if (_monthSource == value)
+				return;
+			
+			if (value is String)
+			{
+				var message:String = resourceManager.getString(
+					"validators", "MSAttribute", [ value ]);
+				throw new Error(message);
+			}
+				
+			removeListenerHandler();	
+				
+			_monthSource = value;
+			
+			addListenerHandler();
+		}
+			
+		//----------------------------------
+		//  validateAsString
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the validateAsString property.
+		 */
+		private var _validateAsString:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var validateAsStringOverride:Object;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  Determines how to validate the value.
+		 *  If set to <code>true</code>, the validator evaluates the value
+		 *  as a String, unless the value has a <code>month</code>,
+		 *  <code>day</code>, or <code>year</code> property.
+		 *  If <code>false</code>, the validator evaluates the value
+		 *  as a Date object. 
+		 *
+		 *  @default true	 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get validateAsString():Object
+		{
+			return _validateAsString;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set validateAsString(value:Object):void
+		{
+			validateAsStringOverride = value;
+
+			_validateAsString = value != null ?
+								Boolean(value) : true;
+			// TODO get from resource bundle
+			// _validateAsString = value != null ?
+			// 					Boolean(value) :
+			// 					resourceManager.getBoolean(
+			// 						"validators", "validateAsString");
+		}
+
+		//----------------------------------
+		//  yearListener
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the yearListener property.
+		 */
+		private var _yearListener:IValidatorListener; 
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  The component that listens for the validation result
+		 *  for the year subfield. 
+		 *  If none is specified, use the value specified
+		 *  for the <code>yearSource</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get yearListener():IValidatorListener
+		{
+			return _yearListener;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set yearListener(value:IValidatorListener):void
+		{
+			if (_yearListener == value)
+				return;
+				
+			removeListenerHandler();	
+				
+			_yearListener = value;
+			
+			addListenerHandler();
+		}
+		
+		//----------------------------------
+		//  yearProperty
+		//----------------------------------
+
+		[Inspectable(category="General")]
+
+		/**
+		 *  Name of the year property to validate. 
+		 *  This property is optional, but if you specify the
+		 *  <code>yearSource</code> property, you should also set this property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var yearProperty:String;
+		
+		//----------------------------------
+		//  yearSource
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the yearSource property.
+		 */
+		private var _yearSource:Object;
+		
+		[Inspectable(category="General")]
+
+		/** 
+		 *  Object that contains the value of the year field.
+		 *  If you specify a value for this property, you must also specify
+		 *  a value for the <code>yearProperty</code> property. 
+		 *  Do not use this property if you set the <code>source</code> 
+		 *  and <code>property</code> properties. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get yearSource():Object
+		{
+			return _yearSource;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set yearSource(value:Object):void
+		{
+			if (_yearSource == value)
+				return;
+			
+			if (value is String)
+			{
+				var message:String = resourceManager.getString(
+					"validators", "YSAttribute", [ value ]);
+				throw new Error(message);
+			}
+				
+			removeListenerHandler();	
+				
+			_yearSource = value;
+			
+			addListenerHandler();
+		}
+			
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  formatError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the formatError property.
+		 */
+		private var _formatError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var formatErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the <code>inputFormat</code> property
+		 *  is not in the correct format.
+		 *
+		 *  @default "Configuration error: Incorrect formatting string." 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get formatError():String
+		{
+			return _formatError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set formatError(value:String):void
+		{
+			formatErrorOverride = value;
+
+			_formatError = value != null ?
+						value :
+						resourceManager.getString(
+							"validators", "formatError");
+		}
+		
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when there are invalid characters in the date.
+		 *
+		 *  @default "Invalid characters in your date."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharErrorDV");
+		}
+		
+		//----------------------------------
+		//  wrongDayError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongDayError property.
+		 */
+		private var _wrongDayError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongDayErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the day is invalid.
+		 *
+		 *  @default "Enter a valid day for the month." 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongDayError():String
+		{
+			return _wrongDayError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongDayError(value:String):void
+		{
+			wrongDayErrorOverride = value;
+
+			_wrongDayError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "wrongDayError");
+		}
+		
+		//----------------------------------
+		//  wrongLengthError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongLengthError property.
+		 */
+		private var _wrongLengthError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongLengthErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the length of the date
+		 *  doesn't match that of the <code>inputFormat</code> property.
+		 *
+		 *  @default "Type the date in the format <i>inputFormat</i>." 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongLengthError():String
+		{
+			return _wrongLengthError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongLengthError(value:String):void
+		{
+			wrongLengthErrorOverride = value;
+
+			_wrongLengthError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "wrongLengthErrorDV");
+		}
+
+		//----------------------------------
+		//  wrongMonthError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongMonthError property.
+		 */
+		private var _wrongMonthError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongMonthErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the month is invalid.
+		 *
+		 *  @default "Enter a month between 1 and 12."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongMonthError():String
+		{
+			return _wrongMonthError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongMonthError(value:String):void
+		{
+			wrongMonthErrorOverride = value;
+
+			_wrongMonthError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "wrongMonthError");
+		}
+		
+		//----------------------------------
+		//  wrongYearError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongYearError property.
+		 */
+		private var _wrongYearError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongYearErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the year is invalid.
+		 *
+		 *  @default "Enter a year between 0 and 9999."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */	
+		public function get wrongYearError():String
+		{
+			return _wrongYearError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongYearError(value:String):void
+		{
+			wrongYearErrorOverride = value;
+
+			_wrongYearError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "wrongYearError");
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private    
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			allowedFormatChars = allowedFormatCharsOverride;
+			inputFormat = inputFormatOverride;
+			validateAsString = validateAsStringOverride;
+					
+			invalidCharError = invalidCharErrorOverride;
+			wrongLengthError = wrongLengthErrorOverride;
+			wrongMonthError = wrongMonthErrorOverride;
+			wrongDayError = wrongDayErrorOverride;
+			wrongYearError = wrongYearErrorOverride;
+			formatError = formatErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method
+		 *  to validate a date.
+		 *
+		 *  <p>You do not call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom validator class, you must implement this method. </p>
+		 *
+		 *  @param value Either a String or an Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+			
+			// Return if there are errors
+			// or if the required property is set to false and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return DateValidator.validateDate(this, value, null);
+		}
+		
+		/**
+		 *  @private
+		 *  Grabs the data for the validator from three different sources.
+		 */
+		override protected function getValueFromSource():Object
+		{
+			var useValue:Boolean = false;
+		
+			var value:Object = {};
+			
+			if (daySource && dayProperty)
+			{
+				value.day = daySource[dayProperty];
+				useValue = true;
+			}
+			
+			if (monthSource && monthProperty)
+			{
+				value.month = monthSource[monthProperty];
+				useValue = true;
+			}
+			
+			if (yearSource && yearProperty)
+			{
+				value.year = yearSource[yearProperty];
+				useValue = true;
+			}
+			
+			return useValue ? value : super.getValueFromSource();
+		}
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/EmailValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/EmailValidator.as
new file mode 100644
index 0000000..f70f4dd
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/EmailValidator.as
@@ -0,0 +1,834 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	// [ResourceBundle("validators")]
+		
+	/**
+	 *  The EmailValidator class validates that a String has a single &#64; sign,
+	 *  a period in the domain name and that the top-level domain suffix has
+	 *  two, three, four, or six characters.
+	 *  IP domain names are valid if they are enclosed in square brackets. 
+	 *  The validator does not check whether the domain and user name
+	 *  actually exist.
+	 *
+	 *  <p>You can use IP domain names if they are enclosed in square brackets; 
+	 *  for example, myname&#64;[206.132.22.1].
+	 *  You can use individual IP numbers from 0 to 255.</p>
+	 *  
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:EmailValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>
+	 *  
+	 *  <pre>
+	 *  &lt;mx:EmailValidator 
+	 *    invalidCharError="Your e-mail address contains invalid characters."
+	 *    invalidDomainError= "The domain in your e-mail address is incorrectly formatted." 
+	 *    invalidIPDomainError="The IP domain in your e-mail address is incorrectly formatted." 
+	 *    invalidPeriodsInDomainError="The domain in your e-mail address has consecutive periods." 
+	 *    missingAtSignError="An at sign (&64;) is missing in your e-mail address."
+	 *    missingPeriodInDomainError="The domain in your e-mail address is missing a period." 
+	 *    missingUsernameError="The username in your e-mail address is missing." 
+	 *    tooManyAtSignsError="Your e-mail address contains too many &64; characters."
+	 *  /&gt;
+	 *  </pre>
+	 *  
+	 *  @includeExample examples/EmailValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class EmailValidator extends Validator
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 */
+		private static const DISALLOWED_LOCALNAME_CHARS:String =
+									"()<>,;:\\\"[] `~!#$%^&*={}|/?'";
+		/**
+		 *  @private
+		 */							
+		private static const DISALLOWED_DOMAIN_CHARS:String =
+									"()<>,;:\\\"[] `~!#$%^&*+={}|/?'";
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Convenience method for calling a validator
+		 *  from within a custom validation function.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The EmailValidator instance.
+		 *
+		 *  @param value A field to validate.
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the value parameter.
+		 *  For example, if the <code>value</code> parameter specifies value.email,
+		 *  the <code>baseField</code> value is "email".
+		 *
+		 *  @return An Array of ValidationResult objects, with one
+		 *  ValidationResult object for each field examined by the validator. 
+		 *
+		 *  @see mx.validators.ValidationResult	 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validateEmail(validator:EmailValidator,
+											value:Object,
+											baseField:String):Array
+		{
+			var results:Array = [];
+		
+			// Validate the domain name
+			// If IP domain, then must follow [x.x.x.x] format
+			// Can not have continous periods.
+			// Must have at least one period.
+			// Must end in a top level domain name that has 2, 3, 4, or 6 characters.
+
+			var emailStr:String = String(value);
+			var username:String = "";
+			var domain:String = "";
+			var n:int;
+			var i:int;
+
+			// Find the @
+			var ampPos:int = emailStr.indexOf("@");
+			if (ampPos == -1)
+			{
+				results.push(new ValidationResult(
+					true, baseField, "missingAtSign",
+					validator.missingAtSignError));
+				return results;
+			}
+			// Make sure there are no extra @s.
+			else if (emailStr.indexOf("@", ampPos + 1) != -1) 
+			{ 
+				results.push(new ValidationResult(
+					true, baseField, "tooManyAtSigns",
+					validator.tooManyAtSignsError));
+				return results;
+			}
+
+			// Separate the address into username and domain.
+			username = emailStr.substring(0, ampPos);
+			domain = emailStr.substring(ampPos + 1);
+
+			// Validate username has no illegal characters
+			// and has at least one character.
+			var usernameLen:int = username.length;
+			if (usernameLen == 0)
+			{
+				results.push(new ValidationResult(
+					true, baseField, "missingUsername",
+					validator.missingUsernameError));
+				return results;
+			}
+
+			for (i = 0; i < usernameLen; i++)
+			{
+				if (DISALLOWED_LOCALNAME_CHARS.indexOf(username.charAt(i)) != -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+			}
+			
+			var domainLen:int = domain.length;
+			
+			// check for IP address
+			if ((domain.charAt(0) == "[") && (domain.charAt(domainLen - 1) == "]"))
+			{
+				// Validate IP address
+				if (!isValidIPAddress(domain.substring(1, domainLen - 1)))
+				{
+					results.push(new ValidationResult(
+							true, baseField, "invalidIPDomain",
+							validator.invalidIPDomainError));
+					return results;
+				}
+			}
+			else
+			{
+				// Must have at least one period
+				var periodPos:int = domain.indexOf(".");
+				var nextPeriodPos:int = 0;
+				var lastDomain:String = "";
+				
+				if (periodPos == -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "missingPeriodInDomain",
+						validator.missingPeriodInDomainError));
+					return results;
+				}
+
+				while (true)
+				{
+					nextPeriodPos = domain.indexOf(".", periodPos + 1);
+					if (nextPeriodPos == -1)
+					{
+						lastDomain = domain.substring(periodPos + 1);
+						if (lastDomain.length != 3 &&
+							lastDomain.length != 2 &&
+							lastDomain.length != 4 &&
+							lastDomain.length != 6)
+						{
+							results.push(new ValidationResult(
+								true, baseField, "invalidDomain",
+								validator.invalidDomainError));
+							return results;
+						}
+						break;
+					}
+					else if (nextPeriodPos == periodPos + 1)
+					{
+						results.push(new ValidationResult(
+							true, baseField, "invalidPeriodsInDomain",
+							validator.invalidPeriodsInDomainError));
+						return results;
+					}
+					periodPos = nextPeriodPos;
+				}
+
+				// Check that there are no illegal characters in the domain.
+				for (i = 0; i < domainLen; i++)
+				{
+					if (DISALLOWED_DOMAIN_CHARS.indexOf(domain.charAt(i)) != -1)
+					{
+						results.push(new ValidationResult(
+							true, baseField, "invalidChar",
+							validator.invalidCharError));
+						return results;
+					}
+				}
+				
+				// Check that the character immediately after the @ is not a period.
+				if (domain.charAt(0) == ".")
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidDomain",
+						validator.invalidDomainError));
+					return results;
+				}
+			}
+
+			return results;
+		}
+		
+		/**
+		 * Validate a given IP address
+		 * 
+		 * If IP domain, then must follow [x.x.x.x] format
+		 * or for IPv6, then follow [x:x:x:x:x:x:x:x] or [x::x:x:x] or some
+		 * IPv4 hybrid, like [::x.x.x.x] or [0:00::192.168.0.1]
+		 *
+		 * @private
+		 */ 
+		private static function isValidIPAddress(ipAddr:String):Boolean
+		{
+			var ipArray:Array = [];
+			var pos:int = 0;
+			var newpos:int = 0;
+			var item:Number;
+			var n:int;
+			var i:int;
+			
+			// if you have :, you're in IPv6 mode
+			// if you have ., you're in IPv4 mode
+			
+			if (ipAddr.indexOf(":") != -1)
+			{
+				// IPv6
+				
+				// validate by splitting on the colons
+				// to make it easier, since :: means zeros, 
+				// lets rid ourselves of these wildcards in the beginning
+				// and then validate normally
+				
+				// get rid of unlimited zeros notation so we can parse better
+				var hasUnlimitedZeros:Boolean = ipAddr.indexOf("::") != -1;
+				if (hasUnlimitedZeros)
+				{
+					ipAddr = ipAddr.replace(/^::/, "");
+					ipAddr = ipAddr.replace(/::/g, ":");
+				}
+				
+				while (true)
+				{
+					newpos = ipAddr.indexOf(":", pos);
+					if (newpos != -1)
+					{
+						ipArray.push(ipAddr.substring(pos,newpos));
+					}
+					else
+					{
+						ipArray.push(ipAddr.substring(pos));
+						break;
+					}
+					pos = newpos + 1;
+				}
+				
+				n = ipArray.length;
+				
+				const lastIsV4:Boolean = ipArray[n-1].indexOf(".") != -1;
+				
+				if (lastIsV4)
+				{
+					// if no wildcards, length must be 7
+					// always, never more than 7
+					if ((ipArray.length != 7 && !hasUnlimitedZeros) || (ipArray.length > 7))
+						return false;
+		
+					for (i = 0; i < n; i++)
+					{
+						if (i == n-1)
+						{
+							// IPv4 part...
+							return isValidIPAddress(ipArray[i]);
+						}
+						
+						item = parseInt(ipArray[i], 16);
+						
+						if (item != 0)
+							return false;
+					}
+				}
+				else
+				{
+				
+					// if no wildcards, length must be 8
+					// always, never more than 8
+					if ((ipArray.length != 8 && !hasUnlimitedZeros) || (ipArray.length > 8))
+						return false;
+					
+					for (i = 0; i < n; i++)
+					{
+						item = parseInt(ipArray[i], 16);
+						
+						if (isNaN(item) || item < 0 || item > 0xFFFF)
+							return false;
+					}
+				}
+				
+				return true;
+			}
+				
+			if (ipAddr.indexOf(".") != -1)
+			{
+				// IPv4
+				
+				// validate by splling on the periods
+				while (true)
+				{
+					newpos = ipAddr.indexOf(".", pos);
+					if (newpos != -1)
+					{
+						ipArray.push(ipAddr.substring(pos,newpos));
+					}
+					else
+					{
+						ipArray.push(ipAddr.substring(pos));
+						break;
+					}
+					pos = newpos + 1;
+				}
+				
+				if (ipArray.length != 4)
+					return false;
+
+				n = ipArray.length;
+				for (i = 0; i < n; i++)
+				{
+					item = Number(ipArray[i]);
+					if (isNaN(item) || item < 0 || item > 255)
+						return false;
+				}
+				
+				return true;
+			}
+			
+			return false;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function EmailValidator()
+		{
+			super();
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there are invalid characters in the e-mail address.
+		 *
+		 *  @default "Your e-mail address contains invalid characters."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharErrorEV");
+		}
+		
+		//----------------------------------
+		//  invalidDomainError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidDomainError property.
+		 */
+		private var _invalidDomainError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidDomainErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the suffix (the top level domain)
+		 *  is not 2, 3, 4 or 6 characters long.
+		 *
+		 *  @default "The domain in your e-mail address is incorrectly formatted."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidDomainError():String
+		{
+			return _invalidDomainError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidDomainError(value:String):void
+		{
+			invalidDomainErrorOverride = value;
+
+			_invalidDomainError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidDomainErrorEV");
+		}
+
+		//----------------------------------
+		//  invalidIPDomainError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidIPDomainError property.
+		 */
+		private var _invalidIPDomainError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidIPDomainErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the IP domain is invalid. The IP domain must be enclosed by square brackets.
+		 *
+		 *  @default "The IP domain in your e-mail address is incorrectly formatted."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidIPDomainError():String
+		{
+			return _invalidIPDomainError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidIPDomainError(value:String):void
+		{
+			invalidIPDomainErrorOverride = value;
+
+			_invalidIPDomainError = value != null ?
+									value :
+									resourceManager.getString(
+										"validators", "invalidIPDomainError");
+		}
+
+		//----------------------------------
+		//  invalidPeriodsInDomainError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidPeriodsInDomainError property.
+		 */
+		private var _invalidPeriodsInDomainError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidPeriodsInDomainErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there are continuous periods in the domain.
+		 *
+		 *  @default "The domain in your e-mail address has continous periods."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidPeriodsInDomainError():String
+		{
+			return _invalidPeriodsInDomainError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidPeriodsInDomainError(value:String):void
+		{
+			invalidPeriodsInDomainErrorOverride = value;
+
+			_invalidPeriodsInDomainError = value != null ?
+										value :
+										resourceManager.getString(
+											"validators", "invalidPeriodsInDomainError");
+		}
+
+		//----------------------------------
+		//  missingAtSignError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the missingAtSignError property.
+		 */
+		private var _missingAtSignError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var missingAtSignErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there is no at sign in the email address.
+		 *
+		 *  @default "An at sign (&64;) is missing in your e-mail address."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get missingAtSignError():String
+		{
+			return _missingAtSignError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set missingAtSignError(value:String):void
+		{
+			missingAtSignErrorOverride = value;
+
+			_missingAtSignError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "missingAtSignError");
+		}
+
+		//----------------------------------
+		//  missingPeriodInDomainError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the missingPeriodInDomainError property.
+		 */
+		private var _missingPeriodInDomainError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var missingPeriodInDomainErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there is no period in the domain.
+		 *
+		 *  @default "The domain in your e-mail address is missing a period."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get missingPeriodInDomainError():String
+		{
+			return _missingPeriodInDomainError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set missingPeriodInDomainError(value:String):void
+		{
+			missingPeriodInDomainErrorOverride = value;
+
+			_missingPeriodInDomainError = value != null ?
+										value :
+										resourceManager.getString(
+											"validators", "missingPeriodInDomainError");
+		}
+
+		//----------------------------------
+		//  missingUsernameError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the missingUsernameError property.
+		 */
+		private var _missingUsernameError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var missingUsernameErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there is no username.
+		 *
+		 *  @default "The username in your e-mail address is missing."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get missingUsernameError():String
+		{
+			return _missingUsernameError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set missingUsernameError(value:String):void
+		{
+			missingUsernameErrorOverride = value;
+
+			_missingUsernameError = value != null ?
+									value :
+									resourceManager.getString(
+										"validators", "missingUsernameError");
+		}
+
+		//----------------------------------
+		//  tooManyAtSignsError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the tooManyAtSignsError property.
+		 */
+		private var _tooManyAtSignsError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var tooManyAtSignsErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when there is more than one at sign in the e-mail address.
+		 *  This property is optional. 
+		 *
+		 *  @default "Your e-mail address contains too many &64; characters."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get tooManyAtSignsError():String
+		{
+			return _tooManyAtSignsError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set tooManyAtSignsError(value:String):void
+		{
+			tooManyAtSignsErrorOverride = value;
+
+			_tooManyAtSignsError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "tooManyAtSignsError");
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private    
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			invalidCharError = invalidCharErrorOverride;
+			invalidDomainError = invalidDomainErrorOverride;
+			invalidIPDomainError = invalidIPDomainErrorOverride;
+			invalidPeriodsInDomainError = invalidPeriodsInDomainErrorOverride;
+			missingAtSignError = missingAtSignErrorOverride;
+			missingPeriodInDomainError = missingPeriodInDomainErrorOverride;
+			missingUsernameError = missingUsernameErrorOverride;
+			tooManyAtSignsError = tooManyAtSignsErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method
+		 *  to validate an e-mail address.
+		 *
+		 *  <p>You do not call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom Validator class, you must implement this method. </p>
+		 *
+		 *  @param value Either a String or an Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+			
+			// Return if there are errors
+			// or if the required property is set to false and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return EmailValidator.validateEmail(this, value, null);
+		}
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IResourceManager.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IResourceManager.as
new file mode 100644
index 0000000..9412c3a
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IResourceManager.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+    import org.apache.flex.events.IEventDispatcher;
+    /**
+     *  Stub to support "calls" to ResourceManager in the validation package.
+     *  To be swapped for the real classes if/when they are written.
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public interface IResourceManager extends IEventDispatcher
+    {
+        function getString(bundleName:String, resourceName:String,
+                        parameters:Array = null,
+                        locale:String = null):String;
+        
+
+    }
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidator.as
new file mode 100644
index 0000000..126af8e
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidator.as
@@ -0,0 +1,118 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+    /**
+     *  This interface specifies the methods and properties that a Validator 
+     *  object must implement. 
+     *  <p>This interface allows to validate multiple data
+     *  types like numbers, currency, phone numbers, zip codes etc that
+     *  are defined in both mx and spark namespaces. The classes 
+     *  mx:Validator and spark:GlobaliationValidatorBase  
+     *  implement this interface. The validateAll() method in these classes use
+     *  this interface type to call the validate() method on 
+     *  multiple validator objects.</p>
+     *  
+     *
+     *  @see mx.validators.Validator
+     *  @see spark.validators.GlobalizationValidatorBase
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public interface IValidator
+    {
+        //----------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //----------------------------------------------------------------------
+
+        //----------------------------------
+        //  enabled
+        //----------------------------------
+
+        /**
+         *  Property to enable/disable validation process.
+         *  <p>Setting this value to <code>false</code> will stop the validator
+         *  from performing validation. 
+         *  When a validator is disabled, it dispatches no events, 
+         *  and the <code>validate()</code> method returns null.</p>
+         *
+         *  @default true
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.1
+         *  @playerversion AIR 2.0
+         *  @productversion Flex 4.5
+         */
+        function get enabled():Boolean;
+        function set enabled(value:Boolean):void;
+        
+        //----------------------------------------------------------------------
+        //
+        //  Methods
+        //
+        //----------------------------------------------------------------------
+
+        //----------------------------------
+        //  validate
+        //----------------------------------
+
+        /**
+         *  Performs validation and optionally notifies
+         *  the listeners of the result. 
+         *
+         *  @param value Optional value to validate.
+         *  If null, then the validator uses the <code>source</code> and
+         *  <code>property</code> properties to determine the value.
+         *  If you specify this argument, you should also set the
+         *  <code>listener</code> property to specify the target component
+         *  for any validation error messages.
+         *
+         *  @param suppressEvents If <code>false</code>, then after validation,
+         *  the validator will notify the listener of the result.
+         *
+         *  @return A ValidationResultEvent object
+         *  containing the results of the validation. 
+         *  For a successful validation, the
+         *  <code>ValidationResultEvent.results</code> Array property is empty. 
+         *  For a validation failure, the
+         *  <code>ValidationResultEvent.results</code> Array property contains
+         *  one ValidationResult object for each field checked by the validator, 
+         *  both for fields that failed the validation and for fields that passed. 
+         *  Examine the <code>ValidationResult.isError</code>
+         *  property to determine if the field passed or failed the validation. 
+         *
+         *  @see mx.events.ValidationResultEvent
+         *  @see mx.validators.ValidationResult
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.1
+         *  @playerversion AIR 2.5
+         *  @productversion Flex 4.5
+         */
+        function validate(value:Object = null,
+                        suppressEvents:Boolean = false):ValidationResultEvent
+    }
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidatorListener.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidatorListener.as
new file mode 100644
index 0000000..d6ee414
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/IValidatorListener.as
@@ -0,0 +1,130 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	/**
+	 *  The interface that components implement to support
+	 *  the Flex data validation mechanism. 
+	 *  The UIComponent class implements this interface.
+	 *  Therefore, any subclass of UIComponent also implements it.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public interface IValidatorListener
+	{
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  errorString
+		//----------------------------------
+
+		/**
+		 *  The text that will be displayed by a component's error tip when a
+		 *  component is monitored by a Validator and validation fails.
+		 *
+		 *  <p>You can use the <code>errorString</code> property to show a 
+		 *  validation error for a component, without actually using
+		 *  a validator class. 
+		 *  When you write a String value to the <code>errorString</code> property, 
+		 *  Flex draws a red border around the component to indicate
+		 *  the validation error, and the String appears in a tooltip
+		 *  as the validation error message when you move  the mouse over
+		 *  the component, just as if a validator detected a validation error.</p>
+		 *
+		 *  <p>To clear the validation error, write an empty String, "", 
+		 *  to the <code>errorString</code> property.</p>
+		 *
+		 *  <p>Note that writing a value to the <code>errorString</code> property 
+		 *  does not trigger the valid or invalid events; it only changes the 
+		 *  border color and displays the validation error message.</p>
+		 *  
+		*  @langversion 3.0
+		*  @playerversion Flash 9
+		*  @playerversion AIR 1.1
+		*  @productversion Flex 3
+		*/
+		function get errorString():String;
+
+		/**
+		 *  @private
+		 */
+		function set errorString(value:String):void;
+
+		//----------------------------------
+		//  validationSubField
+		//----------------------------------
+
+		/**
+		 *  Used by a validator to assign a subfield.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		function get validationSubField():String;
+
+		/**
+		 *  @private
+		 */
+		function set validationSubField(value:String):void;
+
+		//--------------------------------------------------------------------------
+		//
+		//  Event handlers
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Handles both the <code>valid</code> and <code>invalid</code> events
+		 *  from a  validator assigned to this component.  
+		 *
+		 *  <p>You typically handle the <code>valid</code> and <code>invalid</code>
+		 *  events dispatched by a validator by assigning event listeners
+		 *  to the validators. 
+		 *  If you want to handle validation events directly in the component
+		 *  that is being validated, you can override this method
+		 *  to handle the <code>valid</code> and <code>invalid</code> events.
+		 *  From within your implementation, you can use the
+		 *  <code>dispatchEvent()</code> method to dispatch the 
+		 *  <code>valid</code> and <code>invalid</code> events
+		 *  in the case where a validator is also listening for them.</p>
+		 *
+		 *  @param event The event object for the validation.
+		 *
+		 *  @see mx.events.ValidationResultEvent
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		function validationResultHandler(event:ValidationResultEvent):void;
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidator.as
new file mode 100644
index 0000000..736d7e8
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidator.as
@@ -0,0 +1,1197 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+	// [ResourceBundle("validators")]
+
+	/**
+	 *  The NumberValidator class ensures that a String represents a valid number.
+	 *  It can ensure that the input falls within a given range
+	 *  (specified by <code>minValue</code> and <code>maxValue</code>),
+	 *  is an integer (specified by <code>domain</code>),
+	 *  is non-negative (specified by <code>allowNegative</code>),
+	 *  and does not exceed the specified <code>precision</code>.
+	 *  The validator correctly validates formatted numbers (e.g., "12,345.67")
+	 *  and you can customize the <code>thousandsSeparator</code> and
+	 *  <code>decimalSeparator</code> properties for internationalization.
+	 *  
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:NumberValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>
+	 *  
+	 *  <pre>
+	 *  &lt;mx:NumberValidator 
+	 *    allowNegative="true|false" 
+	 *    decimalPointCountError="The decimal separator can only occur once." 
+	 *    decimalSeparator="." 
+	 *    domain="real|int" 
+	 *    exceedsMaxError="The number entered is too large." 
+	 *    integerError="The number must be an integer." 
+	 *    invalidCharError="The input contains invalid characters." 
+	 *    invalidFormatCharsError="One of the formatting parameters is invalid." 
+	 *    lowerThanMinError="The amount entered is too small." 
+	 *    maxValue="NaN" 
+	 *    minValue="NaN" 
+	 *    negativeError="The amount may not be negative." 
+	 *    precision="-1" 
+	 *    precisionError="The amount entered has too many digits beyond the decimal point." 
+	 *    separationError="The thousands separator must be followed by three digits." 
+	 *    thousandsSeparator="," 
+	 *  /&gt;
+	 *  </pre>
+	 *  
+	 *  @includeExample examples/NumberValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class NumberValidator extends Validator
+	{
+		/**
+		 *  Convenience method for calling a validator
+		 *  from within a custom validation function.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The NumberValidator instance.
+		 *
+		 *  @param value A field to validate.
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the <code>value</code> parameter.
+		 *  For example, if the <code>value</code> parameter specifies value.number,
+		 *  the <code>baseField</code> value is "number".
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validateNumber(validator:NumberValidator,
+											value:Object,
+											baseField:String):Array
+		{
+			var results:Array = [];
+
+			// Resource-backed properties of the validator.
+			var allowNegative:Boolean = validator.allowNegative;		
+			var decimalSeparator:String = validator.decimalSeparator;
+			var domain:String = validator.domain;	
+			var maxValue:Number = Number(validator.maxValue);
+			var minValue:Number = Number(validator.minValue);
+			var precision:int = int(validator.precision);
+			var thousandsSeparator:String = validator.thousandsSeparator;
+
+			var input:String = String(value);
+			var len:int = input.length;
+
+			var isNegative:Boolean = false;
+			
+			var i:int;
+			var c:String;
+
+			// Make sure the formatting character parameters are unique,
+			// are not digits or the negative sign,
+			// and that the separators are one character.
+			var invalidFormChars:String = DECIMAL_DIGITS + "-";
+
+			if (decimalSeparator == thousandsSeparator ||
+				invalidFormChars.indexOf(decimalSeparator) != -1 ||
+				invalidFormChars.indexOf(thousandsSeparator) != -1 ||
+				decimalSeparator.length != 1 ||
+				thousandsSeparator.length != 1)
+			{
+				results.push(new ValidationResult(
+					true, baseField, "invalidFormatChar",
+					validator.invalidFormatCharsError));
+				return results;
+			}
+
+			// Check for invalid characters in input.
+			var validChars:String = DECIMAL_DIGITS + "-" +
+									decimalSeparator + thousandsSeparator;
+			for (i = 0; i < len; i++)
+			{
+				c = input.charAt(i);
+				if (validChars.indexOf(c) == -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+			}
+
+			// Check if the input is negative.
+			if (input.charAt(0) == "-")
+			{
+				if (len == 1) // we have only '-' char
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+				else if (len == 2 && input.charAt(1) == '.') // handle "-."
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+
+				// Check if negative input is allowed.
+				if (!allowNegative)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "negative",
+						validator.negativeError));
+					return results;
+				}
+
+				// Strip off the minus sign, update some variables.
+				input = input.substring(1);
+				len--;
+				isNegative = true;
+			}
+
+			// Make sure there's only one decimal point.
+			if (input.indexOf(decimalSeparator) !=
+				input.lastIndexOf(decimalSeparator))
+			{
+				results.push(new ValidationResult(
+					true, baseField, "decimalPointCount",
+					validator.decimalPointCountError));
+				return results;
+			}
+
+			// Make sure every character after the decimal is a digit,
+			// and that there aren't too many digits after the decimal point:
+			// if domain is int there should be none,
+			// otherwise there should be no more than specified by precision.
+			var decimalSeparatorIndex:Number = input.indexOf(decimalSeparator);
+			if (decimalSeparatorIndex != -1)
+			{
+				var numDigitsAfterDecimal:Number = 0;
+
+				if (i == 1 && i == len) // we only have a '.'
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+				
+				for (i = decimalSeparatorIndex + 1; i < len; i++)
+				{
+					// This character must be a digit.
+					if (DECIMAL_DIGITS.indexOf(input.charAt(i)) == -1)
+					{
+						results.push(new ValidationResult(
+							true, baseField, "invalidChar",
+							validator.invalidCharError));
+						return results;
+					}
+
+					++numDigitsAfterDecimal;
+
+					// There may not be any non-zero digits after the decimal
+					// if domain is int.
+					if (domain == NumberValidatorDomainType.INT && input.charAt(i) != "0")
+					{
+						results.push(new ValidationResult(
+							true, baseField,"integer",
+							validator.integerError));
+						return results;
+					}
+
+					// Make sure precision is not exceeded.
+					if (precision != -1 &&
+						numDigitsAfterDecimal > precision)
+					{
+						results.push(new ValidationResult(
+							true, baseField, "precision",
+							validator.precisionError));
+						return results;
+					}
+				}
+			}
+
+			// Make sure the input begins with a digit or a decimal point.
+			if (DECIMAL_DIGITS.indexOf(input.charAt(0)) == -1 &&
+				input.charAt(0) != decimalSeparator)
+			{
+				results.push(new ValidationResult(
+					true, baseField, "invalidChar",
+					validator.invalidCharError));
+				return results;
+			}
+
+			// Make sure that every character before the decimal point
+			// is a digit or is a thousands separator.
+			// If it's a thousands separator,
+			// make sure it's followed by three consecutive digits.
+			var end:int = decimalSeparatorIndex == -1 ?
+						len :
+						decimalSeparatorIndex;
+			for (i = 1; i < end; i++)
+			{
+				c = input.charAt(i);
+				if (c == thousandsSeparator)
+				{
+					if (c == thousandsSeparator)
+					{
+						if ((end - i != 4 &&
+							input.charAt(i + 4) != thousandsSeparator) ||
+							DECIMAL_DIGITS.indexOf(input.charAt(i + 1)) == -1 ||
+							DECIMAL_DIGITS.indexOf(input.charAt(i + 2)) == -1 ||
+							DECIMAL_DIGITS.indexOf(input.charAt(i + 3)) == -1)
+						{
+							results.push(new ValidationResult(
+								true, baseField, "separation",
+								validator.separationError));
+							return results;
+						}
+					}
+				}
+				else if (DECIMAL_DIGITS.indexOf(c) == -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField,"invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+			}
+
+			// Make sure the input is within the specified range.
+			if (!isNaN(minValue) || !isNaN(maxValue))
+			{
+				// First strip off the thousands separators.
+				for (i = 0; i < end; i++)
+				{
+					if (input.charAt(i) == thousandsSeparator)
+					{
+						var left:String = input.substring(0, i);
+						var right:String = input.substring(i + 1);
+						input = left + right;
+					}
+				}
+
+				// Translate the value back into standard english
+				// If the decimalSeperator is not '.' we need to change it to '.' 
+				// so that the number casting will work properly
+				if (validator.decimalSeparator != '.')
+				{
+					var dIndex:int = input.indexOf( validator.decimalSeparator );
+					if (dIndex != -1)
+					{ 
+						var dLeft:String = input.substring(0, dIndex);
+						var dRight:String = input.substring(dIndex + 1);
+						input = dLeft + '.' + dRight;
+					}
+				}
+
+				// Check bounds
+
+				var x:Number = Number(input);
+
+				if (isNegative)
+					x = -x;
+
+				if (!isNaN(minValue) && x < minValue)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "lowerThanMin",
+						validator.lowerThanMinError));
+					return results;
+				}
+				
+				if (!isNaN(maxValue) && x > maxValue)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "exceedsMax",
+						validator.exceedsMaxError));
+					return results;
+				}
+			}
+
+			return results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function NumberValidator()
+		{
+			super();
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  allowNegative
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the allowNegative property.
+		 */
+		private var _allowNegative:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var allowNegativeOverride:Object;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  Specifies whether negative numbers are permitted.
+		 *  Valid values are <code>true</code> or <code>false</code>.
+		 *
+		 *  @default true
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get allowNegative():Object
+		{
+			return _allowNegative;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set allowNegative(value:Object):void
+		{
+			allowNegativeOverride = value;
+
+			_allowNegative = value != null ?
+							Boolean(value) : true;
+			// TODO get from resource bundle
+			// _allowNegative = value != null ?
+			// 				Boolean(value) :
+			// 				resourceManager.getBoolean(
+			// 					"validators", "allowNegative");
+		}
+
+		//----------------------------------
+		//  decimalSeparator
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the decimalSeparator property.
+		 */
+		private var _decimalSeparator:String;
+		
+		/**
+		 *  @private
+		 */
+		private var decimalSeparatorOverride:String;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  The character used to separate the whole
+		 *  from the fractional part of the number.
+		 *  Cannot be a digit and must be distinct from the
+		 *  <code>thousandsSeparator</code>.
+		 *
+		 *  @default "."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */	
+		public function get decimalSeparator():String
+		{
+			return _decimalSeparator;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set decimalSeparator(value:String):void
+		{
+			decimalSeparatorOverride = value;
+
+			_decimalSeparator = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "decimalSeparator");
+		}
+
+		//----------------------------------
+		//  domain
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the domain property.
+		 */
+		private var _domain:String;
+		
+		/**
+		 *  @private
+		 */
+		private var domainOverride:String;
+
+		[Inspectable(category="General", enumeration="int,real", defaultValue="null")]
+
+		/**
+		 *  Type of number to be validated.
+		 *  Permitted values are <code>"real"</code> and <code>"int"</code>.
+		 *
+		 *  <p>In ActionScript, you can use the following constants to set this property: 
+		 *  <code>NumberValidatorDomainType.REAL</code> or
+		 *  <code>NumberValidatorDomainType.INT</code>.</p>
+		 * 
+		 *  @default "real"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get domain():String
+		{
+			return _domain;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set domain(value:String):void
+		{
+			domainOverride = value;
+
+			_domain = value != null ?
+					value :
+					resourceManager.getString(
+						"validators", "numberValidatorDomain");
+		}
+		
+		//----------------------------------
+		//  maxValue
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Storage for the maxValue property.
+		 */
+		private var _maxValue:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var maxValueOverride:Object;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  Maximum value for a valid number. A value of NaN means there is no maximum.
+		 *
+		 *  @default NaN
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get maxValue():Object
+		{
+			return _maxValue;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set maxValue(value:Object):void
+		{
+			maxValueOverride = value;
+
+			_maxValue = value != null ?
+						Number(value) : Number.MAX_VALUE;
+			// TODO get from resource bundle
+			// _maxValue = value != null ?
+			// 			Number(value) :
+			// 			resourceManager.getNumber(
+			// 				"validators", "maxValue");
+		}
+
+		//----------------------------------
+		//  minValue
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the minValue property.
+		 */
+		private var _minValue:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var minValueOverride:Object;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  Minimum value for a valid number. A value of NaN means there is no minimum.
+		 *
+		 *  @default NaN
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get minValue():Object
+		{
+			return _minValue;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set minValue(value:Object):void
+		{
+			minValueOverride = value;
+
+			_minValue = value != null ?
+						Number(value) : Number.MIN_VALUE;
+			// TODO get from resource bundle
+			// _minValue = value != null ?
+			// 			Number(value) :
+			// 			resourceManager.getNumber(
+			// 				"validators", "minValue");
+		}
+		
+		//----------------------------------
+		//  precision
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the precision property.
+		 */
+		private var _precision:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var precisionOverride:Object;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  The maximum number of digits allowed to follow the decimal point.
+		 *  Can be any nonnegative integer. 
+		 *  Note: Setting to <code>0</code> has the same effect
+		 *  as setting <code>domain</code> to <code>"int"</code>.
+		 *  A value of -1 means it is ignored.
+		 *
+		 *  @default -1
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get precision():Object
+		{
+			return _precision;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set precision(value:Object):void
+		{
+			precisionOverride = value;
+
+			_precision = value != null ?
+						int(value) : 10;
+
+			// TODO get from resource bundle
+			// _precision = value != null ?
+			// 			int(value) :
+			// 			resourceManager.getInt(
+			// 				"validators", "numberValidatorPrecision");
+		}
+		
+		//----------------------------------
+		//  thousandsSeparator
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the thousandsSeparator property.
+		 */
+		private var _thousandsSeparator:String;
+		
+		/**
+		 *  @private
+		 */
+		private var thousandsSeparatorOverride:String;
+
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  The character used to separate thousands
+		 *  in the whole part of the number.
+		 *  Cannot be a digit and must be distinct from the
+		 *  <code>decimalSeparator</code>.
+		 *
+		 *  @default ","
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get thousandsSeparator():String
+		{
+			return _thousandsSeparator;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set thousandsSeparator(value:String):void
+		{
+			thousandsSeparatorOverride = value;
+
+			_thousandsSeparator = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "thousandsSeparator");
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  decimalPointCountError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the decimalPointCountError property.
+		 */
+		private var _decimalPointCountError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var decimalPointCountErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the decimal separator character occurs more than once.
+		 *
+		 *  @default "The decimal separator can occur only once."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get decimalPointCountError():String
+		{
+			return _decimalPointCountError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set decimalPointCountError(value:String):void
+		{
+			decimalPointCountErrorOverride = value;
+
+			_decimalPointCountError = value != null ?
+									value :
+									resourceManager.getString(
+										"validators", "decimalPointCountError");
+		}
+		
+		//----------------------------------
+		//  exceedsMaxError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the exceedsMaxError property.
+		 */
+		private var _exceedsMaxError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var exceedsMaxErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value exceeds the <code>maxValue</code> property.
+		 *
+		 *  @default "The number entered is too large."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get exceedsMaxError():String
+		{
+			return _exceedsMaxError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set exceedsMaxError(value:String):void
+		{
+			exceedsMaxErrorOverride = value;
+
+			_exceedsMaxError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "exceedsMaxErrorNV");
+		}
+		
+		//----------------------------------
+		//  integerError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the integerError property.
+		 */
+		private var _integerError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var integerErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the number must be an integer, as defined 
+		 * by the <code>domain</code> property.
+		 *
+		 *  @default "The number must be an integer."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get integerError():String
+		{
+			return _integerError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set integerError(value:String):void
+		{
+			integerErrorOverride = value;
+
+			_integerError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "integerError");
+		}
+
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value contains invalid characters.
+		 *
+		 *  @default The input contains invalid characters."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */	
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharError");
+		}
+
+		//----------------------------------
+		//  invalidFormatCharsError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidFormatCharsError property.
+		 */
+		private var _invalidFormatCharsError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidFormatCharsErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value contains invalid format characters, which means that 
+		 *  it contains a digit or minus sign (-) as a separator character, 
+		 *  or it contains two or more consecutive separator characters.
+		 *
+		 *  @default "One of the formatting parameters is invalid."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidFormatCharsError():String
+		{
+			return _invalidFormatCharsError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidFormatCharsError(value:String):void
+		{
+			invalidFormatCharsErrorOverride = value;
+
+			_invalidFormatCharsError = value != null ?
+									value :
+									resourceManager.getString(
+										"validators", "invalidFormatCharsError");
+		}
+
+		//----------------------------------
+		//  lowerThanMinError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the lowerThanMinError property.
+		 */
+		private var _lowerThanMinError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var lowerThanMinErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value is less than <code>minValue</code>.
+		 *
+		 *  @default "The amount entered is too small."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get lowerThanMinError():String
+		{
+			return _lowerThanMinError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set lowerThanMinError(value:String):void
+		{
+			lowerThanMinErrorOverride = value;
+
+			_lowerThanMinError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "lowerThanMinError");
+		}
+
+		//----------------------------------
+		//  negativeError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the negativeError property.
+		 */
+		private var _negativeError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var negativeErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value is negative and the 
+		 *  <code>allowNegative</code> property is <code>false</code>.
+		 *
+		 *  @default "The amount may not be negative."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get negativeError():String
+		{
+			return _negativeError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set negativeError(value:String):void
+		{
+			negativeErrorOverride = value;
+
+			_negativeError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "negativeError");
+		}
+
+		//----------------------------------
+		//  precisionError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the precisionError property.
+		 */
+		private var _precisionError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var precisionErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value has a precision that exceeds the value defined 
+		 *  by the precision property.
+		 *
+		 *  @default "The amount entered has too many digits beyond the decimal point."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get precisionError():String
+		{
+			return _precisionError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set precisionError(value:String):void
+		{
+			precisionErrorOverride = value;
+
+			_precisionError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "precisionError");
+		}
+
+		//----------------------------------
+		//  separationError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the separationError property.
+		 */
+		private var _separationError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var separationErrorOverride:String;
+
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the thousands separator is in the wrong location.
+		 *
+		 *  @default "The thousands separator must be followed by three digits."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get separationError():String
+		{
+			return _separationError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set separationError(value:String):void
+		{
+			separationErrorOverride = value;
+
+			_separationError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "separationError");
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private    
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			allowNegative = allowNegativeOverride;		
+			decimalSeparator = decimalSeparatorOverride;
+			domain = domainOverride;	
+			maxValue = maxValueOverride;
+			minValue = minValueOverride;
+			precision = precisionOverride;
+			thousandsSeparator = thousandsSeparatorOverride;
+
+			decimalPointCountError = decimalPointCountErrorOverride;
+			exceedsMaxError = exceedsMaxErrorOverride;
+			integerError = integerErrorOverride;
+			invalidCharError = invalidCharErrorOverride;
+			invalidFormatCharsError = invalidFormatCharsErrorOverride;
+			lowerThanMinError = lowerThanMinErrorOverride;
+			negativeError = negativeErrorOverride;
+			precisionError = precisionErrorOverride;
+			separationError = separationErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method 
+		 *  to validate a number.
+		 *
+		 *  <p>You do not call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom Validator class, you must implement this method. </p>
+		 *
+		 *  @param value Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+			
+			// Return if there are errors
+			// or if the required property is set to <code>false</code> and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return NumberValidator.validateNumber(this, value, null);
+		}
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidatorDomainType.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidatorDomainType.as
new file mode 100644
index 0000000..638cd1c
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/NumberValidatorDomainType.as
@@ -0,0 +1,64 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+	
+/**
+ *  The NumberValidatorDomainType class defines the values 
+ *  for the <code>domain</code> property of the NumberValidator class.
+ *
+ *  @see org.apache.flex.utils.validation.NumberValidator
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class NumberValidatorDomainType
+{
+	
+
+	//--------------------------------------------------------------------------
+	//
+	//  Class constants
+	//
+	//--------------------------------------------------------------------------
+	
+	/**
+	 *  Specifies to validate an integer number.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const INT:String = "int";
+	
+	/**
+	 *  Specifies to validate a real number.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const REAL:String = "real";
+}
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/PhoneNumberValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/PhoneNumberValidator.as
new file mode 100644
index 0000000..dac84b8
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/PhoneNumberValidator.as
@@ -0,0 +1,425 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+	import org.apache.flex.utils.StringUtil;
+
+
+	// [ResourceBundle("validators")]
+
+	/**
+	 *  The PhoneNumberValidator class validates that a string
+	 *  is a valid phone number.
+	 *  A valid phone number contains at least 10 digits,
+	 *  plus additional formatting characters.
+	 *  The validator does not check if the phone number
+	 *  is an actual active phone number.
+	 *  
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:PhoneNumberValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>
+	 *  
+	 *  <pre>
+	 *  &lt;mx:PhoneNumberValidator 
+	 *    allowedFormatChars="()- .+" 
+	 *    invalidCharError="Your telephone number contains invalid characters."
+	 * 	  minDigits="10"
+	 *    wrongLengthError="Your telephone number must contain at least 10 digits."
+	 *  /&gt;
+	 *  </pre>
+	 *  
+	 *  @includeExample examples/PhoneNumberValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class PhoneNumberValidator extends Validator
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Convenience method for calling a validator
+		 *  from within a custom validation function.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The PhoneNumberValidator instance.
+		 *
+		 *  @param value A field to validate.
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the <code>value</code> parameter.
+		 *  For example, if the <code>value</code> parameter specifies value.phone,
+		 *  the <code>baseField</code> value is "phone".
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validatePhoneNumber(validator:PhoneNumberValidator,
+												value:Object,
+												baseField:String):Array
+		{
+			var results:Array = [];
+			
+			// Resource-backed properties of the validator.
+			var allowedFormatChars:String = validator.allowedFormatChars;
+
+			var resourceManager:IResourceManager = ResourceManager.getInstance();
+
+			var valid:String =  DECIMAL_DIGITS + allowedFormatChars;
+			var len:int = value.toString().length;
+			var digitLen:int = 0;
+			var n:int;
+			var i:int;
+			var minDigits:Number = Number(validator.minDigits);
+			
+			n = allowedFormatChars.length;
+			for (i = 0; i < n; i++)
+			{
+				if (DECIMAL_DIGITS.indexOf(allowedFormatChars.charAt(i)) != -1)
+				{
+					var message:String = resourceManager.getString(
+						"validators", "invalidFormatChars");
+					throw new Error(message);
+				}
+			}
+
+			for (i = 0; i < len; i++)
+			{
+				var temp:String = "" + value.toString().substring(i, i + 1);
+				if (valid.indexOf(temp) == -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+				if (valid.indexOf(temp) <= 9)
+					digitLen++;
+			}
+
+			if (!isNaN(minDigits) && digitLen < minDigits)
+			{
+				results.push(new ValidationResult(
+					true, baseField, "wrongLength",
+					StringUtil.substitute(validator.wrongLengthError, minDigits)));
+				return results;
+			}
+
+			return results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function PhoneNumberValidator()
+		{
+			super();
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  allowedFormatChars
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the allowedFormatChars property.
+		 */
+		private var _allowedFormatChars:String;
+
+		/**
+		 *  @private
+		 */
+		private var allowedFormatCharsOverride:String;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  The set of allowable formatting characters.
+		 *
+		 *  @default "()- .+"
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get allowedFormatChars():String
+		{
+			return _allowedFormatChars;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set allowedFormatChars(value:String):void
+		{
+			if (value != null)
+			{
+				var n:int = value.length;
+				for (var i:int = 0; i < n; i++)
+				{
+					if (DECIMAL_DIGITS.indexOf(value.charAt(i)) != -1)
+					{
+						var message:String = resourceManager.getString(
+							"validators", "invalidFormatChars");
+						throw new Error(message);
+					}
+				}
+			}
+
+			allowedFormatCharsOverride = value;
+
+			_allowedFormatChars = value != null ?
+								value :
+								resourceManager.getString(
+									"validators",
+									"phoneNumberValidatorAllowedFormatChars");
+		}
+
+		//----------------------------------
+		//  minDigits
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the minDigits property.
+		 */
+		private var _minDigits:Object;
+		
+		/**
+		 *  @private
+		 */
+		private var minDigitsOverride:Object;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/** 
+		 *  Minimum number of digits for a valid phone number.
+		 *  A value of NaN means this property is ignored.
+		 *
+		 *  @default 10
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get minDigits():Object
+		{
+			return _minDigits;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set minDigits(value:Object):void
+		{
+			minDigitsOverride = value;
+
+			_minDigits = value != null ?
+						Number(value) : 10;
+
+			// TODO get from resource bundle
+			// _minDigits = value != null ?
+			// 			Number(value) :
+			// 			resourceManager.getNumber(
+			// 				"validators", "minDigitsPNV");
+		}
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the value contains invalid characters.
+		 *
+		 *  @default "Your telephone number contains invalid characters."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharErrorPNV");
+		}
+
+		//----------------------------------
+		//  wrongLengthError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongLengthError property.
+		 */
+		private var _wrongLengthError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongLengthErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/** 
+		 *  Error message when the value has fewer than 10 digits.
+		 *
+		 *  @default "Your telephone number must contain at least 10 digits."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongLengthError():String
+		{
+			return _wrongLengthError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongLengthError(value:String):void
+		{
+			wrongLengthErrorOverride = value;
+
+			_wrongLengthError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "wrongLengthErrorPNV");
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private    
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			allowedFormatChars = allowedFormatCharsOverride;
+			minDigits = minDigitsOverride;
+			invalidCharError = invalidCharErrorOverride;
+			wrongLengthError = wrongLengthErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method
+		 *  to validate a phone number.
+		 *
+		 *  <p>You do not typically call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom Validator class, you must implement this method. </p>
+		 *
+		 *  @param value Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult 
+		 *  object for each field examined by the validator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+			
+			// Return if there are errors
+			// or if the required property is set to <code>false</code> and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return PhoneNumberValidator.validatePhoneNumber(this, value, null);
+		}
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidationResult.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidationResult.as
new file mode 100644
index 0000000..f78ca03
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidationResult.as
@@ -0,0 +1,146 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+/**
+ *  The RegExpValidator class dispatches the <code>valid</code>
+ *  and <code>invalid</code> events. 
+ *  For an <code>invalid</code> event, the event object
+ *  is an instance of the ValidationResultEvent class, 
+ *  and the <code>ValidationResultEvent.results</code> property
+ *  contains an Array of ValidationResult objects.
+ *
+ *  <p>However, for a <code>valid</code> event, the 
+ *  <code>ValidationResultEvent.results</code> property contains 
+ *  an Array of RegExpValidationResult objects.
+ *  The RegExpValidationResult class is a child class
+ *  of the ValidationResult class, and contains additional properties 
+ *  used with regular expressions.</p>
+ *
+ *  @see mx.events.ValidationResultEvent
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class RegExpValidationResult extends ValidationResult
+{
+
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/** 
+	 *  Constructor
+	 *  
+     *  @param isError Pass <code>true</code> if there was a validation error.
+     *
+     *  @param subField Name of the subfield of the validated Object.
+     *
+     *  @param errorCode  Validation error code.
+     *
+     *  @param errorMessage Validation error message.
+     *
+     *  @param matchedString Matching substring.
+     *
+     *  @param matchedIndex Index of the matching String.
+     *
+     *  @param matchedSubstrings Array of substring matches.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public function RegExpValidationResult(isError:Boolean, 
+										   subField:String = "", 
+										   errorCode:String = "", 
+										   errorMessage:String = "",
+										   matchedString:String = "",
+										   matchedIndex:int = 0,
+										   matchedSubstrings:Array = null)
+	{
+		super(isError, subField, errorCode, errorMessage);
+		
+		this.matchedString = matchedString;
+		this.matchedIndex = matchedIndex;
+		this.matchedSubstrings = matchedSubstrings ? matchedSubstrings : [];
+	}
+	
+	//--------------------------------------------------------------------------
+	//
+	//  Properties
+	//
+	//--------------------------------------------------------------------------
+
+	//--------------------------------------------------------------------------
+	//  matchedIndex
+	//--------------------------------------------------------------------------
+
+	/** 
+	 *  An integer that contains the starting index
+	 *  in the input String of the match.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var matchedIndex:int;
+
+	//--------------------------------------------------------------------------
+	//  matchedString
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  A String that contains the substring of the input String
+	 *  that matches the regular expression.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var matchedString:String;
+
+	//--------------------------------------------------------------------------
+	//  matchedSubstrings
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  An Array of Strings that contains parenthesized
+	 *  substring matches, if any. 
+	 *	If no substring matches are found, this Array is of length 0.
+	 *	Use <code>matchedSubStrings[0]</code> to access
+	 *  the first substring match.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var matchedSubstrings:Array;
+}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidator.as
new file mode 100644
index 0000000..66e018f
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/RegExpValidator.as
@@ -0,0 +1,434 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+    // [ResourceBundle("validators")]
+
+    /** 
+     *  The RegExpValidator class lets you use a regular expression
+     *  to validate a field. 
+     *  You pass a regular expression to the validator using the
+     *  <code>expression</code> property, and additional flags
+     *  to control the regular expression pattern matching 
+     *  using the <code>flags</code> property. 
+     *
+     *  <p>The validation is successful if the validator can find a match
+     *  of the regular expression in the field to validate.
+     *  A validation error occurs when the validator finds no match.</p>
+     *
+     *  <p>The RegExpValidator class dispatches the <code>valid</code>
+     *  and <code>invalid</code> events.
+     *  For an <code>invalid</code> event, the event object is an instance
+     *  of the ValidationResultEvent class, and it contains an Array
+     *  of ValidationResult objects.</p>
+     *
+     *  <p>However, for a <code>valid</code> event, the ValidationResultEvent
+     *  object contains an Array of RegExpValidationResult objects.
+     *  The RegExpValidationResult class is a child class of the
+     *  ValidationResult class, and contains additional properties 
+     *  used with regular expressions, including the following:</p>
+     *  <ul>
+     *    <li><code>matchedIndex</code> An integer that contains the starting 
+     *      index in the input String of the match.</li>
+     *    <li><code>matchedString</code> A String that contains the substring 
+     *      of the input String that matches the regular expression.</li>
+     *    <li><code>matchedSubStrings</code> An Array of Strings that contains 
+     *      parenthesized substring matches, if any. If no substring matches are found, 
+     *      this Array is of length 0.  Use matchedSubStrings[0] to access the 
+     *      first substring match.</li>
+     *  </ul>
+     *  
+     *  @mxml
+     *
+     *  <p>The <code>&lt;mx:RegExpValidator&gt;</code> tag 
+     *  inherits all of the tag attributes of its superclass,
+     *  and adds the following tag attributes:</p>
+     *  
+     *  <pre>
+     *  &lt;mx:RegExpValidator
+     *    expression="<i>No default</i>" 
+     *    flags="<i>No default</i>" 
+     *    noExpressionError="The expression is missing." 
+     *    noMatchError="The field is invalid." 
+     *  /&gt;
+     *  </pre>
+     *
+     *  @includeExample examples/RegExValidatorExample.mxml
+     *  
+     *  @see mx.validators.RegExpValidationResult
+     *  @see mx.validators.ValidationResult
+     *  @see RegExp
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class RegExpValidator extends Validator
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+
+        /** 
+         *  Constructor
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */     
+        public function RegExpValidator()
+        {
+            super();
+        }
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Variables
+        //
+        //--------------------------------------------------------------------------
+
+        /** 
+         *  @private
+         */     
+        private var regExp:RegExp;
+        
+        /** 
+         *  @private
+         */     
+        private var foundMatch:Boolean = false;
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  expression
+        //----------------------------------
+
+        /** 
+         *  @private
+         *  Storage for the expression property.
+         */     
+        private var _expression:String;
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  The regular expression to use for validation. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get expression():String
+        {
+            return _expression;
+        }
+            
+        /** 
+         *  @private
+         */     
+        public function set expression(value:String):void
+        {
+            if (_expression != value)
+            {
+                _expression = value;
+
+                createRegExp();
+            }
+        }
+        
+        //----------------------------------
+        //  flags
+        //----------------------------------
+        
+        /** 
+         *  @private
+         *  Storage for the flags property.
+         */     
+        private var _flags:String;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /**
+         *  The regular expression flags to use when matching.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get flags():String
+        {
+            return _flags;
+        }
+        
+        /** 
+         *  @private
+         */     
+        public function set flags(value:String):void
+        {
+            if (_flags != value)
+            {
+                _flags = value;
+
+                createRegExp();
+            }
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties: Errors
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  noExpressionError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the noExpressionError property.
+         */
+        private var _noExpressionError:String;
+        
+        /**
+         *  @private
+         */
+        private var noExpressionErrorOverride:String;
+        
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when there is no regular expression specifed. 
+         *  The default value is "The expression is missing."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get noExpressionError():String
+        {
+            return _noExpressionError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set noExpressionError(value:String):void
+        {
+            noExpressionErrorOverride = value;
+
+            _noExpressionError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "noExpressionError");
+        }
+
+        //----------------------------------
+        //  noMatchError
+        //----------------------------------
+            
+        /**
+         *  @private
+         *  Storage for the noMatchError property.
+         */
+        private var _noMatchError:String;
+        
+        /**
+         *  @private
+         */
+        private var noMatchErrorOverride:String;
+        
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when there are no matches to the regular expression. 
+         *  The default value is "The field is invalid."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get noMatchError():String
+        {
+            return _noMatchError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set noMatchError(value:String):void
+        {
+            noMatchErrorOverride = value;
+
+            _noMatchError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "noMatchError");
+        }
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Overridden methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private    
+         */
+        override protected function resourcesChanged():void
+        {
+            super.resourcesChanged();
+
+            noExpressionError = noExpressionErrorOverride;  
+            noMatchError = noMatchErrorOverride;
+        }
+
+        /**
+         *  Override of the base class <code>doValidation()</code> method
+         *  to validate a regular expression.
+         *
+         *  <p>You do not call this method directly;
+         *  Flex calls it as part of performing a validation.
+         *  If you create a custom Validator class, you must implement this method. </p>
+         *
+         *  @param value Object to validate.
+         *
+         *  @return For an invalid result, an Array of ValidationResult objects,
+         *  with one ValidationResult object for each field examined by the validator. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        override protected function doValidation(value:Object):Array
+        {
+            var results:Array = super.doValidation(value);
+            
+            // Return if there are errors
+            // or if the required property is set to <code>false</code> and length is 0.
+            var val:String = value ? String(value) : "";
+            if (results.length > 0 || ((val.length == 0) && !required))
+                return results;
+
+            return validateRegExpression(value);
+        }
+        
+        /**
+         *  @private
+         */
+        override protected function handleResults(
+                                        errorResults:Array):ValidationResultEvent
+        {
+            var result:ValidationResultEvent;
+            
+            if (foundMatch)
+            {
+                result = new ValidationResultEvent(ValidationResultEvent.VALID);
+                result.results = errorResults;
+            }
+            else
+            {
+                result = super.handleResults(errorResults);
+            }
+            
+            foundMatch = false;    
+            
+            return result;  
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private
+         */
+        private function createRegExp():void
+        {
+            regExp = new RegExp(_expression,_flags);
+        }
+        
+        /**
+         *  @private 
+         *  Performs validation on the validator
+         */     
+        private function validateRegExpression(value:Object):Array
+        {
+            var results:Array = [];
+            foundMatch = false;
+        
+            if (regExp && _expression != "")
+            {
+                var result:Object = regExp.exec(String(value));
+                if (regExp.global)
+                {
+                    while (result != null) 
+                    {
+                        results.push(new RegExpValidationResult(
+                            false, null, "", "", result[0],
+                            result.index, result.slice(1)));
+                        result = regExp.exec(String(value));
+                        foundMatch = true;
+                    }
+                }
+                else if (result != null)
+                {
+                    results.push(new RegExpValidationResult(
+                        false, null, "", "", result[0],
+                        result.index, result.slice(1)));                
+                    foundMatch = true;
+                }   
+                
+                if (results.length == 0)
+                {
+                    results.push(new ValidationResult(
+                        true, null, "noMatch",
+                        noMatchError));
+                }
+            }
+            else
+            {
+                results.push(new ValidationResult(
+                    true, null, "noExpression",
+                    noExpressionError));
+            }
+            
+            return results;
+        }
+    }
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ResourceManager.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ResourceManager.as
new file mode 100644
index 0000000..c7017e7
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ResourceManager.as
@@ -0,0 +1,91 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+    import org.apache.flex.events.EventDispatcher;
+
+    /**
+     *  This class is used to get a single instance of the IResourceManager
+     *  implementation.
+     *  The IResourceManager and IResourceBundle interfaces work together
+     *  to provide internationalization support for Flex applications.
+     *
+     *  <p>A single instance of an IResourceManager implementation
+     *  manages all localized resources
+     *  for a Flex application.</p>
+     *  
+     *  @see mx.resources.IResourceManager
+     *  @see mx.resources.IResourceBundle
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class ResourceManager extends EventDispatcher implements IResourceManager
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class variables
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private
+         *  The sole instance of the ResourceManager.
+         */
+        private static var instance:IResourceManager;
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Class methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Gets the single instance of the ResourceManager class.
+         *  This object manages all localized resources for a Flex application.
+         *  
+         *  @return An object implementing IResourceManager.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public static function getInstance():IResourceManager
+        {
+            if (!instance)
+            {
+                instance  = new ResourceManager();
+            }
+            
+            return instance;
+        }
+        public function getString(bundleName:String, resourceName:String,
+                        parameters:Array = null,
+                        locale:String = null):String{
+                            return resourceName;
+                        }
+    }
+
+}
\ No newline at end of file
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/SocialSecurityValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/SocialSecurityValidator.as
new file mode 100644
index 0000000..3d7eb79
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/SocialSecurityValidator.as
@@ -0,0 +1,433 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+	// [ResourceBundle("validators")]
+
+	/**
+	 *  The SocialSecurityValidator class validates that a String
+	 *  is a valid United States Social Security number.
+	 *  It does not check whether it is an existing Social Security number.
+	 *
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;mx:SocialSecurityValidator&gt;</code> tag
+	 *  inherits all of the tag attributes of its superclass,
+	 *  and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;mx:SocialSecurityValidator
+	 *    allowedFormatChars=" -"
+	 *    invalidCharError="You entered invalid characters in your Social Security number."
+	 *    wrongFormatError="The Social Security number must be 9 digits or in the form NNN-NN-NNNN."
+	 *    zeroStartError="Invalid Social Security number; the number cannot start with 000."
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @includeExample examples/SocialSecurityValidatorExample.mxml
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class SocialSecurityValidator extends Validator
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Convenience method for calling a validator.
+		 *  Each of the standard Flex validators has a similar convenience method.
+		 *
+		 *  @param validator The SocialSecurityValidator instance.
+		 *
+		 *  @param value A field to validate.
+		 *
+		 *  @param baseField Text representation of the subfield
+		 *  specified in the <code>value</code> parameter.
+		 *  For example, if the <code>value</code> parameter specifies
+		 *  value.social, the <code>baseField</code> value is <code>social</code>.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult
+		 *  object for each field examined by the validator.
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function validateSocialSecurity(
+									validator:SocialSecurityValidator,
+									value:Object,
+									baseField:String):Array
+		{
+			var results:Array = [];
+
+			// Resource-backed properties of the validator.
+			var allowedFormatChars:String = validator.allowedFormatChars;
+
+			var resourceManager:IResourceManager = ResourceManager.getInstance();
+
+			var hyphencount:int = 0;
+			var len:int = value.toString().length;
+			var checkForFormatChars:Boolean = false;
+
+			var n:int;
+			var i:int;
+
+			if ((len != 9) && (len != 11))
+			{
+				results.push(new ValidationResult(
+					true, baseField, "wrongFormat",
+					validator.wrongFormatError));
+				return results;
+			}
+
+			n = allowedFormatChars.length;
+			for (i = 0; i < n; i++)
+			{
+				if (DECIMAL_DIGITS.indexOf(allowedFormatChars.charAt(i)) != -1)
+				{
+					var message:String = resourceManager.getString(
+						"validators", "invalidFormatChars");
+					throw new Error(message);
+				}
+			}
+
+			if (len == 11)
+				checkForFormatChars = true;
+
+			for (i = 0; i < len; i++)
+			{
+				var allowedChars:String;
+				if (checkForFormatChars && (i == 3 || i == 6))
+					allowedChars = allowedFormatChars;
+				else
+					allowedChars = DECIMAL_DIGITS;
+
+				if (allowedChars.indexOf(value.charAt(i)) == -1)
+				{
+					results.push(new ValidationResult(
+						true, baseField, "invalidChar",
+						validator.invalidCharError));
+					return results;
+				}
+			}
+
+			if (value.substring(0, 3) == "000")
+			{
+				results.push(new ValidationResult(
+					true, baseField, "zeroStart",
+					validator.zeroStartError));
+				return results;
+			}
+
+			return results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function SocialSecurityValidator()
+		{
+			super();
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  allowedFormatChars
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		private var _allowedFormatChars:String;
+
+		/**
+		 *  @private
+		 */
+		private var allowedFormatCharsOverride:String;
+		
+		[Inspectable(category="General", defaultValue="null")]
+
+		/**
+		 *  Specifies the set of formatting characters allowed in the input.
+		 *
+		 *  @default "()- .+" // ?????
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get allowedFormatChars():String
+		{
+			return _allowedFormatChars;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set allowedFormatChars(value:String):void
+		{
+			if (value != null)
+			{
+				var n:int = value.length;
+				for (var i:int = 0; i < n; i++)
+				{
+					if (DECIMAL_DIGITS.indexOf(value.charAt(i)) != -1)
+					{
+						var message:String = resourceManager.getString(
+							"validators", "invalidFormatChars");
+						throw new Error(message);
+					}
+				}
+			}
+
+			allowedFormatCharsOverride = value;
+
+			_allowedFormatChars = value != null ?
+								value :
+								resourceManager.getString(
+									"validators",
+									"socialSecurityValidatorAllowedFormatChars");
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties: Errors
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  invalidCharError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the invalidCharError property.
+		 */
+		private var _invalidCharError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var invalidCharErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value contains characters
+		 *  other than digits and formatting characters
+		 *  defined by the <code>allowedFormatChars</code> property.
+		 *
+		 *  @default "You entered invalid characters in your Social Security number."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get invalidCharError():String
+		{
+			return _invalidCharError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set invalidCharError(value:String):void
+		{
+			invalidCharErrorOverride = value;
+
+			_invalidCharError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "invalidCharErrorSSV");
+		}
+
+		//----------------------------------
+		//  wrongFormatError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the wrongFormatError property.
+		 */
+		private var _wrongFormatError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var wrongFormatErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value is incorrectly formatted.
+		 *
+		 *  @default "The Social Security number must be 9 digits or in the form NNN-NN-NNNN."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get wrongFormatError():String
+		{
+			return _wrongFormatError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set wrongFormatError(value:String):void
+		{
+			wrongFormatErrorOverride = value;
+
+			_wrongFormatError = value != null ?
+								value :
+								resourceManager.getString(
+									"validators", "wrongFormatError");
+		}
+
+		//----------------------------------
+		//  zeroStartError
+		//----------------------------------
+
+		/**
+		 *  @private
+		 *  Storage for the zeroStartError property.
+		 */
+		private var _zeroStartError:String;
+		
+		/**
+		 *  @private
+		 */
+		private var zeroStartErrorOverride:String;
+		
+		[Inspectable(category="Errors", defaultValue="null")]
+
+		/**
+		 *  Error message when the value contains an invalid Social Security number.
+		 *
+		 *  @default "Invalid Social Security number; the number cannot start with 000."
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get zeroStartError():String
+		{
+			return _zeroStartError;
+		}
+
+		/**
+		 *  @private
+		 */
+		public function set zeroStartError(value:String):void
+		{
+			zeroStartErrorOverride = value;
+
+			_zeroStartError = value != null ?
+							value :
+							resourceManager.getString(
+								"validators", "zeroStartError");
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 */
+		override protected function resourcesChanged():void
+		{
+			super.resourcesChanged();
+
+			allowedFormatChars = allowedFormatChars;
+
+			invalidCharError = invalidCharErrorOverride;
+			wrongFormatError = wrongFormatErrorOverride;
+			zeroStartError = zeroStartErrorOverride;
+		}
+
+		/**
+		 *  Override of the base class <code>doValidation()</code> method
+		 *  to validate a Social Security number.
+		 *
+		 *  <p>You do not call this method directly;
+		 *  Flex calls it as part of performing a validation.
+		 *  If you create a custom Validator class, you must implement this method.</p>
+		 *
+		 *  @param value Object to validate.
+		 *
+		 *  @return An Array of ValidationResult objects, with one ValidationResult
+		 *  object for each field examined by the validator.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		override protected function doValidation(value:Object):Array
+		{
+			var results:Array = super.doValidation(value);
+
+			// Return if there are errors
+			// or if the required property is set to <code>false</code> and length is 0.
+			var val:String = value ? String(value) : "";
+			if (results.length > 0 || ((val.length == 0) && !required))
+				return results;
+			else
+				return SocialSecurityValidator.validateSocialSecurity(this, value, null);
+		}
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/StringValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/StringValidator.as
new file mode 100644
index 0000000..6f71fa6
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/StringValidator.as
@@ -0,0 +1,390 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+    
+    import org.apache.flex.utils.StringUtil;
+    // [ResourceBundle("validators")]
+
+    /**
+     *  The StringValidator class validates that the length of a String 
+     *  is within a specified range. 
+     *  
+     *  @mxml
+     *  
+     *  <p>The <code>&lt;mx:StringValidator&gt;</code> tag
+     *  inherits all of the tag attributes of its superclass,
+     *  and add the following tag attributes:</p>
+     *  
+     *  <pre>
+     *  &lt;mx:StringValidator
+     *    maxLength="NaN" 
+     *    minLength="NaN" 
+     *    tooLongError="This string is longer than the maximum allowed length. This must be less than {0} characters long." 
+     *    tooShortError="This string is shorter than the minimum allowed length. This must be at least {0} characters long." 
+     *  /&gt;
+     *  </pre>
+     *  
+     *  @includeExample examples/StringValidatorExample.mxml
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class StringValidator extends Validator
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Convenience method for calling a validator.
+         *  Each of the standard Flex validators has a similar convenience method.
+         *
+         *  @param validator The StringValidator instance.
+         *
+         *  @param value A field to validate.
+         *
+         *  @param baseField Text representation of the subfield
+         *  specified in the <code>value</code> parameter.
+         *  For example, if the <code>value</code> parameter specifies
+         *  value.mystring, the <code>baseField</code> value
+         *  is <code>"mystring"</code>.
+         *
+         *  @return An Array of ValidationResult objects, with one
+         *  ValidationResult  object for each field examined by the validator. 
+         *
+         *  @see mx.validators.ValidationResult
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public static function validateString(validator:StringValidator,
+                                            value:Object,
+                                            baseField:String = null):Array
+        {
+            var results:Array = [];
+            
+            // Resource-backed properties of the validator.
+            var maxLength:Number = Number(validator.maxLength);
+            var minLength:Number = Number(validator.minLength);
+
+            var val:String = value != null ? String(value) : "";
+
+            if (!isNaN(maxLength) && val.length > maxLength)
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "tooLong",
+                    StringUtil.substitute(validator.tooLongError, maxLength)));
+                return results;
+            }
+
+            if (!isNaN(minLength) && val.length < minLength)
+            {
+                results.push(new ValidationResult(
+                    true, baseField, "tooShort",
+                    StringUtil.substitute(validator.tooShortError, minLength)));
+                return results;
+            }
+
+            return results;
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Constructor.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function StringValidator()
+        {
+            super();
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  maxLength
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the maxLength property.
+         */
+        private var _maxLength:Object;
+        
+        /**
+         *  @private
+         */
+        private var maxLengthOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /** 
+         *  Maximum length for a valid String. 
+         *  A value of NaN means this property is ignored.
+         *
+         *  @default NaN
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get maxLength():Object
+        {
+            return _maxLength;
+        }
+
+        /**
+         *  @private
+         */
+        public function set maxLength(value:Object):void
+        {
+            maxLengthOverride = value;
+
+            _maxLength = value != null ?
+                        Number(value) : Number.MAX_VALUE;
+			// TODO get from resource bundle
+            // _maxLength = value != null ?
+            //             Number(value) :
+            //             resourceManager.getNumber(
+            //                 "validators", "maxLength");
+        }
+        
+        //----------------------------------
+        //  minLength
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the minLength property.
+         */
+        private var _minLength:Object;
+        
+        /**
+         *  @private
+         */
+        private var minLengthOverride:Object;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /** 
+         *  Minimum length for a valid String.
+         *  A value of NaN means this property is ignored.
+         *
+         *  @default NaN
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get minLength():Object
+        {
+            return _minLength;
+        }
+
+        /**
+         *  @private
+         */
+        public function set minLength(value:Object):void
+        {
+            minLengthOverride = value;
+
+            _minLength = value != null ?
+                        Number(value) : Number.MIN_VALUE;
+
+			// TODO get from resource bundle
+            // _minLength = value != null ?
+            //             Number(value) :
+            //             resourceManager.getNumber(
+            //                 "validators", "minLength");
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties: Errors
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  tooLongError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the tooLongError property.
+         */
+        private var _tooLongError:String;
+
+        /**
+         *  @private
+         */
+        private var tooLongErrorOverride:String;
+        
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when the String is longer
+         *  than the <code>maxLength</code> property.
+         *
+         *  @default "This string is longer than the maximum allowed length. This must be less than {0} characters long."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get tooLongError():String 
+        {
+            return _tooLongError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set tooLongError(value:String):void
+        {
+            tooLongErrorOverride = value;
+
+            _tooLongError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "tooLongError");
+        }
+
+        //----------------------------------
+        //  tooShortError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the tooShortError property.
+         */
+        private var _tooShortError:String;
+        
+        /**
+         *  @private
+         */
+        private var tooShortErrorOverride:String;
+        
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when the string is shorter
+         *  than the <code>minLength</code> property.
+         *
+         *  @default "This string is shorter than the minimum allowed length. This must be at least {0} characters long."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get tooShortError():String 
+        {
+            return _tooShortError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set tooShortError(value:String):void
+        {
+            tooShortErrorOverride = value;
+
+            _tooShortError = value != null ?
+                            value :
+                            resourceManager.getString(
+                                "validators", "tooShortError");
+        }
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Overridden methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private    
+         */
+        override protected function resourcesChanged():void
+        {
+            super.resourcesChanged();
+
+            maxLength = maxLengthOverride;
+            minLength = minLengthOverride;
+
+            tooLongError = tooLongErrorOverride;
+            tooShortError = tooShortErrorOverride;
+        }
+
+        /**
+         *  Override of the base class <code>doValidation()</code> method
+         *  to validate a String.
+         *
+         *  <p>You do not call this method directly;
+         *  Flex calls it as part of performing a validation.
+         *  If you create a custom Validator class, you must implement this method.</p>
+         *
+         *  @param value Object to validate.
+         *
+         *  @return An Array of ValidationResult objects, with one ValidationResult 
+         *  object for each field examined by the validator. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        override protected function doValidation(value:Object):Array
+        {
+            var results:Array = super.doValidation(value);
+            
+            // Return if there are errors
+            // or if the required property is set to false and length is 0.
+            var val:String = value ? String(value) : "";
+            if (results.length > 0 || ((val.length == 0) && !required))
+                return results;
+            else
+                return StringValidator.validateString(this, value, null);
+        }
+    }
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResult.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResult.as
new file mode 100644
index 0000000..ed785fd
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResult.as
@@ -0,0 +1,146 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+	/**
+	 *  The ValidationResult class contains the results of a validation. 
+	 *
+	 *  <p>The ValidationResultEvent class defines the event object
+	 *  that is passed to event listeners for the <code>valid</code>
+	 *  and <code>invalid</code> validator events. 
+	 *  The class also defines the <code>results</code> property,
+	 *  which contains an Array of ValidationResult objects,
+	 *  one for each field examined by the validator.
+	 *  This lets you access the ValidationResult objects
+	 *  from within an event listener.</p>
+	 *
+	 *  @see mx.events.ValidationResultEvent
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class ValidationResult
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor
+		 *
+		 *  @param isError Pass <code>true</code> if there was a validation error.
+		 *
+		 *  @param subField Name of the subfield of the validated Object.
+		 *
+		 *  @param errorCode  Validation error code.
+		 *
+		 *  @param errorMessage Validation error message.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function ValidationResult(isError:Boolean, subField:String = "",
+										errorCode:String = "",
+										errorMessage:String = "")
+		{
+			super();
+
+			this.isError = isError;
+			this.subField = subField;
+			this.errorMessage = errorMessage;
+			this.errorCode = errorCode;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  errorCode
+		//----------------------------------
+
+		/**
+		 *  The validation error code
+		 *  if the value of the <code>isError</code> property is <code>true</code>.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var errorCode:String;
+
+		//----------------------------------
+		//  errorMessage
+		//----------------------------------
+
+		/**
+		 *  The validation error message
+		 *  if the value of the <code>isError</code> property is <code>true</code>.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var errorMessage:String;
+		
+		//----------------------------------
+		//  isError
+		//----------------------------------
+
+		/**
+		 *  Contains <code>true</code> if the field generated a validation failure.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var isError:Boolean;
+		
+		//----------------------------------
+		//  subField
+		//----------------------------------
+
+		/**
+		 *  The name of the subfield that the result is associated with.
+		 *  Some validators, such as CreditCardValidator and DateValidator,
+		 *  validate multiple subfields at the same time.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var subField:String;
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResultEvent.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResultEvent.as
new file mode 100644
index 0000000..40c1ac5
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ValidationResultEvent.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 org.apache.flex.utils.validation
+{
+	import org.apache.flex.events.Event;
+
+	/**
+	 *  The ValidationResultEvent class represents the event object 
+	 *  passed to the listener for the <code>valid</code> validator event
+	 *  or the <code>invalid</code> validator event. 
+	 *
+	 *  @see mx.validators.Validator
+	 *  @see mx.validators.ValidationResult
+	 *  @see mx.validators.RegExpValidationResult
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class ValidationResultEvent extends Event
+	{
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  The <code>ValidationResultEvent.INVALID</code> constant defines the value of the 
+		 *  <code>type</code> property of the event object for an <code>invalid</code> event.
+		 *  The value of this constant is "invalid".
+		 *
+		 *  <p>The properties of the event object have the following values:</p>
+		 *  <table class="innertable">
+		 *     <tr><th>Property</th><th>Value</th></tr>
+		 *     <tr><td><code>bubbles</code></td><td>false</td></tr>
+		 *     <tr><td><code>cancelable</code></td><td>false</td></tr>
+		 *     <tr><td><code>currentTarget</code></td><td>The Object that defines the 
+		 *       event listener that handles the event. For example, if you use 
+		 *       <code>myButton.addEventListener()</code> to register an event listener, 
+		 *       myButton is the value of the <code>currentTarget</code>. </td></tr>
+		 *     <tr><td><code>field</code></td><td>The name of the field that failed validation.</td></tr>
+		 *     <tr><td><code>message</code></td><td>A single string that contains 
+		 *       every error message from all of the ValidationResult objects in the results Array.</td></tr>
+		 *     <tr><td><code>results</code></td><td>An array of ValidationResult objects, 
+		 *       one per validated field.</td></tr>
+		 *     <tr><td><code>target</code></td><td>The Object that dispatched the event; 
+		 *       it is not always the Object listening for the event. 
+		 *       Use the <code>currentTarget</code> property to always access the 
+		 *       Object listening for the event.</td></tr>
+		 *  </table>
+		 *
+		 *  @eventType invalid 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const INVALID:String = "invalid";
+
+		/**
+		 *  The <code>ValidationResultEvent.VALID</code> constant defines the value of the 
+		 *  <code>type</code> property of the event object for a <code>valid</code>event.
+		 *  The value of this constant is "valid".
+		 *
+		 *  <p>The properties of the event object have the following values:</p>
+		 *  <table class="innertable">
+		 *     <tr><th>Property</th><th>Value</th></tr>
+		 *     <tr><td><code>bubbles</code></td><td>false</td></tr>
+		 *     <tr><td><code>cancelable</code></td><td>false</td></tr>
+		 *     <tr><td><code>currentTarget</code></td><td>The Object that defines the 
+		 *       event listener that handles the event. For example, if you use 
+		 *       <code>myButton.addEventListener()</code> to register an event listener, 
+		 *       myButton is the value of the <code>currentTarget</code>. </td></tr>
+		 *     <tr><td><code>field</code></td><td>An empty String.</td></tr>
+		 *     <tr><td><code>message</code></td><td>An empty String.</td></tr>
+		 *     <tr><td><code>results</code></td><td>An empty Array.</td></tr>
+		 *     <tr><td><code>target</code></td><td>The Object that dispatched the event; 
+		 *       it is not always the Object listening for the event. 
+		 *       Use the <code>currentTarget</code> property to always access the 
+		 *       Object listening for the event.</td></tr>
+		 *  </table>
+		 *
+		 *  @eventType valid 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const VALID:String = "valid";
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *
+		 *  @param type The event type; indicates the action that caused the event.
+		 *
+		 *  @param bubbles Specifies whether the event can bubble up the 
+		 *  display list hierarchy.
+		 *
+		 *  @param cancelable Specifies whether the behavior associated with the event can be prevented.
+		 *
+		 *  @param field The name of the field that failed validation and triggered the event.
+		 *
+		 *  @param results An array of ValidationResult objects, one per validated field. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function ValidationResultEvent(type:String, bubbles:Boolean = false,
+											cancelable:Boolean = false,
+											field:String = null,
+											results:Array = null)
+		{
+			super(type, bubbles, cancelable);
+
+			this.field = field;
+			this.results = results;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  field
+		//----------------------------------
+
+		/**
+		 *  The name of the field that failed validation and triggered the event.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var field:String;
+		
+		//----------------------------------
+		//  message
+		//----------------------------------
+
+		/**
+		 *  A single string that contains every error message from all
+		 *  of the ValidationResult objects in the results Array.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function get message():String
+		{
+			var msg:String = "";;
+			
+			var n:int = results.length;
+			for (var i:int = 0; i < n; ++i)
+			{
+				if (results[i].isError)
+				{
+					msg += msg == "" ? "" : "\n";
+					msg += results[i].errorMessage;
+				}
+			}
+			
+			return msg;
+		}
+
+		//----------------------------------
+		//  results
+		//----------------------------------
+
+		/**
+		 *  An array of ValidationResult objects, one per validated field. 
+		 *
+		 *  @see mx.validators.ValidationResult
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public var results:Array;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods: Event
+		//
+		//--------------------------------------------------------------------------
+
+	}
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/Validator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/Validator.as
new file mode 100644
index 0000000..e137a6c
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/Validator.as
@@ -0,0 +1,1167 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+    import org.apache.flex.events.Event;
+    import org.apache.flex.events.EventDispatcher;
+    import org.apache.flex.core.IDocument;
+    import org.apache.flex.events.IEventDispatcher;
+
+    //--------------------------------------
+    //  Events
+    //--------------------------------------
+
+    /**
+     *  Dispatched when validation succeeds.
+     *
+     *  @eventType org.apache.flex.utils.validation.ValidationResultEvent.VALID 
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    [Event(name="valid", type="org.apache.flex.utils.validation.ValidationResultEvent")]
+
+    /** 
+     *  Dispatched when validation fails.
+     *
+     *  @eventType org.apache.flex.utils.validation.ValidationResultEvent.INVALID 
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    [Event(name="invalid", type="org.apache.flex.utils.validation.ValidationResultEvent")]
+
+    //--------------------------------------
+    //  Other metadata
+    //--------------------------------------
+
+    // [ResourceBundle("core")]
+    // [ResourceBundle("validators")]
+
+    /**
+     *  The Validator class is the base class for all Flex validators. 
+     *  This class implements the ability for a validator to make a field
+     *  required, which means that the user must enter a value in the field
+     *  or the validation fails.
+     * 
+     *  @mxml
+     *
+     *  <p>The Validator class defines the following tag attributes, 
+     *  which all of its subclasses inherit:</p>
+     *
+     *  <pre>
+     *  &lt;mx:Validator 
+     *    enabled="true|false" 
+     *    listener="<i>Value of the source property</i>" 
+     *    property="<i>No default</i>" 
+     *    required="true|false" 
+     *    requiredFieldError="This field is required." 
+     *    source="<i>No default</i>" 
+     *    trigger="<i>Value of the source property</i>" 
+     *    triggerEvent="valueCommit" 
+     *  /&gt;
+     *  </pre>
+     *
+     *  @see org.apache.flex.utils.validation.ValidationResultEvent
+     *  @see mx.validators.ValidationResult
+     *  @see mx.validators.RegExpValidationResult
+     *
+     *  @includeExample examples/SimpleValidatorExample.mxml
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class Validator extends EventDispatcher implements IDocument,IValidator
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class constants
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  A string containing the upper- and lower-case letters
+         *  of the Roman alphabet  ("A" through "Z" and "a" through "z").
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected static const ROMAN_LETTERS:String =
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+        /**
+         *  A String containing the decimal digits 0 through 9.    
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */ 
+        protected static const DECIMAL_DIGITS:String = "0123456789";
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Class methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Invokes all the validators in the <code>validators</code> Array.
+         *  Returns an Array containing one ValidationResultEvent object 
+         *  for each validator that failed.
+         *  Returns an empty Array if all validators succeed. 
+         *
+         *  @param validators An Array containing the Validator objects to execute. 
+         *
+         *  @return Array of ValidationResultEvent objects, where the Array
+         *  contains one ValidationResultEvent object for each validator
+         *  that failed. 
+         *  The Array is empty if all validators succeed.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public static function validateAll(validators:Array):Array
+        {   
+            var result:Array = [];
+
+            var n:int = validators.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                var v:IValidator = validators[i] as IValidator;
+                if (v && v.enabled)
+                {
+                    var resultEvent:ValidationResultEvent = v.validate();
+                    
+                    if (resultEvent.type != ValidationResultEvent.VALID)
+                        result.push(resultEvent);
+                }
+            }   
+            
+            return result;
+        }
+        
+        /**
+         *  @private
+         */
+        private static function findObjectFromString(doc:Object,
+                                                    value:String):Object
+        {
+            var obj:Object = doc;
+            var parts:Array = value.split(".");
+
+            var n:int = parts.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                try
+                {
+                    obj = obj[parts[i]];
+                    
+                    // There's no guarantee that the objects have
+                    // already been created when this function fires;
+                    // for example, in the deferred instantiation case,
+                    // this function fires before the object for validation
+                    // has been created.
+                    if (obj == null)
+                    {
+                        //return true;
+                    }
+                }
+                catch(error:Error)
+                {
+                    if ((error is TypeError) &&
+                        (error.message.indexOf("null has no properties") != -1))
+                    {
+                        var resourceManager:IResourceManager =
+                            ResourceManager.getInstance();
+                        var message:String = resourceManager.getString(
+                            "validators", "fieldNotFound", [ value ]);
+                        throw new Error(message);
+                    }
+                    else
+                    {                    
+                        throw error;
+                    }
+                }
+            }
+            
+            return obj;
+        }
+        
+        /**
+         *  @private
+         */
+        private static function trimString(str:String):String
+        {
+            var startIndex:int = 0;
+            while (str.indexOf(' ', startIndex) == startIndex)
+            {
+                ++startIndex;
+            }
+
+            var endIndex:int = str.length - 1;
+            while (str.lastIndexOf(' ', endIndex) == endIndex)
+            {
+                --endIndex;
+            }
+
+            return endIndex >= startIndex ?
+                str.slice(startIndex, endIndex + 1) :
+                "";
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Constructor.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function Validator()
+        {
+            super();
+
+            // Register as a weak listener for "change" events from ResourceManager.
+            // If Validators registered as a strong listener,
+            // they wouldn't get garbage collected.
+            // resourceManager.addEventListener(
+            //     Event.CHANGE, resourceManager_changeHandler, false, 0, true);
+
+            resourcesChanged();
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Variables
+        //
+        //--------------------------------------------------------------------------
+
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  actualTrigger
+        //----------------------------------
+
+        /**
+         *  Contains the trigger object, if any,
+         *  or the source object. Used to determine the listener object
+         *  for the <code>triggerEvent</code>. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function get actualTrigger():IEventDispatcher
+        {
+            if (_trigger)
+                return _trigger;
+            
+            else if (_source)
+                return _source as IEventDispatcher;
+                
+            return null;            
+        }
+        
+        //----------------------------------
+        //  actualListeners
+        //----------------------------------
+
+        /**
+         *  Contains an Array of listener objects, if any,  
+         *  or the source object. Used to determine which object
+         *  to notify about the validation result.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function get actualListeners():Array
+        {
+            var result:Array = [];
+        
+            if (_listener)
+                result.push(_listener);
+            
+            else if (_source)
+                result.push(_source);
+                
+            return result;
+        }
+        
+        //----------------------------------
+        //  enabled
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the enabled property.
+         */
+        private var _enabled:Boolean = true;
+        
+        [Inspectable(category="General", defaultValue="true")]
+
+        /** 
+         *  Setting this value to <code>false</code> will stop the validator
+         *  from performing validation. 
+         *  When a validator is disabled, it dispatch no events, 
+         *  and the <code>validate()</code> method returns null.
+         *
+         *  @default true
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get enabled():Boolean
+        {
+            return _enabled;
+        }
+
+        /**
+         *  @private
+         */
+        public function set enabled(value:Boolean):void
+        {
+            _enabled = value;
+        }
+        
+        //----------------------------------
+        //  listener
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the listener property.
+         */
+        private var _listener:Object;
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  Specifies the validation listener.
+         *
+         *  <p>If you do not specify a listener,
+         *  Flex uses the value of the <code>source</code> property. 
+         *  After Flex determines the source component,
+         *  it changes the border color of the component,
+         *  displays an error message for a failure,
+         *  or hides any existing error message for a successful validation.</p>
+         *
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        
+        /* This behavior has been removed.
+        *  <p>If Flex does not find an appropriate listener, 
+        *  validation errors propagate to the Application object, causing Flex 
+        *  to display an Alert box containing the validation error message.</p>
+        *
+        *  <p>Specifying <code>this</code> causes the validation error
+        *  to propagate to the Application object, 
+        *  and displays an Alert box containing the validation error message.</p>
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+        public function get listener():Object
+        {
+            return _listener;
+        }
+
+        /**
+         *  @private
+         */
+        public function set listener(value:Object):void
+        {
+            removeListenerHandler();    
+            _listener = value;
+            addListenerHandler();   
+        }
+        
+        //----------------------------------
+        //  property
+        //----------------------------------    
+        
+        /**
+         *  @private
+         *  Storage for the property property.
+         */
+        private var _property:String;
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  A String specifying the name of the property
+         *  of the <code>source</code> object that contains 
+         *  the value to validate.
+         *  The property is optional, but if you specify <code>source</code>,
+         *  you should set a value for this property as well.
+         *  
+         *  @default null
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get property():String
+        {
+            return _property;
+        }
+
+        /**
+         *  @private
+         */
+        public function set property(value:String):void
+        {
+            _property = value;
+        }
+        
+        //----------------------------------
+        //  required
+        //----------------------------------
+
+        [Inspectable(category="General", defaultValue="true")]
+        
+        /**
+         *  If <code>true</code>, specifies that a missing or empty 
+         *  value causes a validation error. 
+         *  
+         *  @default true
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public var required:Boolean = true;
+        
+        //----------------------------------
+        //  resourceManager
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the resourceManager property.
+         */
+        private var _resourceManager:IResourceManager = ResourceManager.getInstance();
+        
+        /**
+         *  @private
+         *  This metadata suppresses a trace() in PropertyWatcher:
+         *  "warning: unable to bind to property 'resourceManager' ..."
+         */
+        [Bindable("unused")]
+        
+        /**
+         *  @copy mx.core.UIComponent#resourceManager
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function get resourceManager():IResourceManager
+        {
+            return _resourceManager;
+        }
+
+        //----------------------------------
+        //  source
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the source property.
+         */
+        private var _source:Object;
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  Specifies the object containing the property to validate. 
+         *  Set this to an instance of a component or a data model. 
+         *  You use data binding syntax in MXML to specify the value.
+         *  This property supports dot-delimited Strings
+         *  for specifying nested properties. 
+         *
+         *  If you specify a value to the <code>source</code> property,
+         *  then you should specify a value to the <code>property</code>
+         *  property as well. 
+         *  The <code>source</code> property is optional.
+         *  
+         *  @default null
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get source():Object
+        {
+            return _source;
+        }
+        
+        /**
+         *  @private
+         */
+        public function set source(value:Object):void
+        {
+            if (_source == value)
+                return;
+            
+            if (value is String)
+            {
+                var message:String = resourceManager.getString(
+                    "validators", "SAttribute", [ value ]);
+                throw new Error(message);
+            }
+            
+            // Remove the listener from the old source.
+            removeTriggerHandler();
+            removeListenerHandler();
+            
+            _source = value;
+                    
+            // Listen for the trigger event on the new source.
+            addTriggerHandler();    
+            addListenerHandler();   
+        }
+
+        //----------------------------------
+        //  subFields
+        //----------------------------------
+
+        /**
+         *  An Array of Strings containing the names for the properties contained 
+         *  in the <code>value</code> Object passed to the <code>validate()</code> method. 
+         *  For example, CreditCardValidator sets this property to 
+         *  <code>[ "cardNumber", "cardType" ]</code>. 
+         *  This value means that the <code>value</code> Object 
+         *  passed to the <code>validate()</code> method 
+         *  should contain a <code>cardNumber</code> and a <code>cardType</code> property. 
+         *
+         *  <p>Subclasses of the Validator class that 
+         *  validate multiple data fields (like CreditCardValidator and DateValidator)
+         *  should assign this property in their constructor. </p>
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected var subFields:Array = [];
+
+        //----------------------------------
+        //  trigger
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the trigger property.
+         */
+        private var _trigger:IEventDispatcher;
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  Specifies the component generating the event that triggers the validator. 
+         *  If omitted, by default Flex uses the value of the <code>source</code> property.
+         *  When the <code>trigger</code> dispatches a <code>triggerEvent</code>,
+         *  validation executes. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get trigger():IEventDispatcher
+        {
+            return _trigger;
+        }
+        
+        /**
+         *  @private
+         */
+        public function set trigger(value:IEventDispatcher):void
+        {
+            removeTriggerHandler();
+            _trigger = value;
+            addTriggerHandler();    
+        }
+        
+        //----------------------------------
+        //  triggerEvent
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the triggerEvent property.
+         */
+        //TODO What is this for (changed the old value to a literal to make error go away)?
+        private var _triggerEvent:String = "valueCommit";
+        
+        [Inspectable(category="General")]
+
+        /**
+         *  Specifies the event that triggers the validation. 
+         *  If omitted, Flex uses the <code>valueCommit</code> event. 
+         *  Flex dispatches the <code>valueCommit</code> event
+         *  when a user completes data entry into a control.
+         *  Usually this is when the user removes focus from the component, 
+         *  or when a property value is changed programmatically.
+         *  If you want a validator to ignore all events,
+         *  set <code>triggerEvent</code> to the empty string ("").
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get triggerEvent():String
+        {
+            return _triggerEvent;
+        }
+        
+        /**
+         *  @private
+         */
+        public function set triggerEvent(value:String):void
+        {
+            if (_triggerEvent == value)
+                return;
+                
+            removeTriggerHandler();
+            _triggerEvent = value;
+            addTriggerHandler();
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties: Errors
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  requiredFieldError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the requiredFieldError property.
+         */
+        private var _requiredFieldError:String;
+        
+        /**
+         *  @private
+         */
+        private var requiredFieldErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+        
+        /**
+         *  Error message when a value is missing and the 
+         *  <code>required</code> property is <code>true</code>. 
+         *  
+         *  @default "This field is required."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get requiredFieldError():String
+        {
+            return _requiredFieldError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set requiredFieldError(value:String):void
+        {
+            requiredFieldErrorOverride = value;
+
+            _requiredFieldError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "requiredFieldError");
+        }
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  This method is called when a Validator is constructed,
+         *  and again whenever the ResourceManager dispatches
+         *  a <code>"change"</code> Event to indicate
+         *  that the localized resources have changed in some way.
+         * 
+         *  <p>This event will be dispatched when you set the ResourceManager's
+         *  <code>localeChain</code> property, when a resource module
+         *  has finished loading, and when you call the ResourceManager's
+         *  <code>update()</code> method.</p>
+         *
+         *  <p>Subclasses should override this method and, after calling
+         *  <code>super.resourcesChanged()</code>, do whatever is appropriate
+         *  in response to having new resource values.</p>
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function resourcesChanged():void
+        {
+            requiredFieldError = requiredFieldErrorOverride;
+        }
+
+        /**
+         *  @private
+         */
+        private function addTriggerHandler():void
+        {
+            if (actualTrigger)
+                actualTrigger.addEventListener(_triggerEvent, triggerHandler);
+        }
+        
+        /**
+         *  @private
+         */
+        private function removeTriggerHandler():void
+        {
+            if (actualTrigger)  
+                actualTrigger.removeEventListener(_triggerEvent, triggerHandler);
+        }
+        
+        /**
+         *  Sets up all of the listeners for the 
+         *  <code>valid</code> and <code>invalid</code>
+         *  events dispatched from the validator. Subclasses of the Validator class 
+         *  should first call the <code>removeListenerHandler()</code> method, 
+         *  and then the <code>addListenerHandler()</code> method if 
+         *  the value of one of their listeners or sources changes. 
+         *  The CreditCardValidator and DateValidator classes use this function internally. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function addListenerHandler():void
+        {
+            var actualListener:Object;
+            var listeners:Array = actualListeners;
+        
+            var n:int = listeners.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                actualListener = listeners[i];
+                if (actualListener is IValidatorListener)
+                {
+                    addEventListener(ValidationResultEvent.VALID,
+                                    IValidatorListener(actualListener).validationResultHandler); 
+
+                    addEventListener(ValidationResultEvent.INVALID,
+                                    IValidatorListener(actualListener).validationResultHandler); 
+                }
+            }
+        }
+        
+        /**
+         *  Disconnects all of the listeners for the 
+         *  <code>valid</code> and <code>invalid</code>
+         *  events dispatched from the validator. Subclasses should first call the
+         *  <code>removeListenerHandler()</code> method and then the 
+         *  <code>addListenerHandler</code> method if 
+         *  the value of one of their listeners or sources changes. 
+         *  The CreditCardValidator and DateValidator classes use this function internally. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function removeListenerHandler():void
+        {
+            var actualListener:Object;
+            var listeners:Array = actualListeners;
+        
+            var n:int = listeners.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                actualListener = listeners[i];
+                if (actualListener is IValidatorListener)
+                {
+                    removeEventListener(ValidationResultEvent.VALID,
+                                        IValidatorListener(actualListener).validationResultHandler); 
+                                        
+                    removeEventListener(ValidationResultEvent.INVALID,
+                                        IValidatorListener(actualListener).validationResultHandler); 
+                }
+            }
+        }
+
+        /**
+         *  Returns <code>true</code> if <code>value</code> is not null. 
+         * 
+         *  @param value The value to test.
+         *
+         *  @return <code>true</code> if <code>value</code> is not null.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function isRealValue(value:Object):Boolean
+        {
+            return (value != null); 
+        }
+
+        /**
+         *  Performs validation and optionally notifies
+         *  the listeners of the result. 
+         *
+         *  @param value Optional value to validate.
+         *  If null, then the validator uses the <code>source</code> and
+         *  <code>property</code> properties to determine the value.
+         *  If you specify this argument, you should also set the
+         *  <code>listener</code> property to specify the target component
+         *  for any validation error messages.
+         *
+         *  @param suppressEvents If <code>false</code>, then after validation,
+         *  the validator will notify the listener of the result.
+         *
+         *  @return A ValidationResultEvent object
+         *  containing the results of the validation. 
+         *  For a successful validation, the
+         *  <code>ValidationResultEvent.results</code> Array property is empty. 
+         *  For a validation failure, the
+         *  <code>ValidationResultEvent.results</code> Array property contains
+         *  one ValidationResult object for each field checked by the validator, 
+         *  both for fields that failed the validation and for fields that passed. 
+         *  Examine the <code>ValidationResult.isError</code>
+         *  property to determine if the field passed or failed the validation. 
+         *
+         *  @see mx.events.ValidationResultEvent
+         *  @see mx.validators.ValidationResult
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function validate(
+                            value:Object = null,
+                            suppressEvents:Boolean = false):ValidationResultEvent
+        {   
+            if (value == null)
+                value = getValueFromSource();   
+            
+            if (isRealValue(value) || required)
+            {
+                // Validate if the target is required or our value is non-null.
+                return processValidation(value, suppressEvents);
+            }
+            else
+            {
+                // We assume if value is null and required is false that
+                // validation was successful.
+                var resultEvent:ValidationResultEvent = 
+                    new ValidationResultEvent(ValidationResultEvent.VALID);
+                if (!suppressEvents && _enabled)
+                {
+                    dispatchEvent(resultEvent);
+                }
+                return resultEvent; 
+            } 
+        }
+        
+        /**
+         *  Returns the Object to validate. Subclasses, such as the 
+         *  CreditCardValidator and DateValidator classes, 
+         *  override this method because they need
+         *  to access the values from multiple subfields. 
+         *
+         *  @return The Object to validate.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function getValueFromSource():Object
+        {
+            var message:String;
+
+            if (_source && _property)
+            {
+                return _source[_property];
+            }
+
+            else if (!_source && _property)
+            {
+                message = resourceManager.getString(
+                    "validators", "SAttributeMissing");
+                throw new Error(message);
+            }
+
+            else if (_source && !_property)
+            {
+                message = resourceManager.getString(
+                    "validators", "PAttributeMissing");
+                throw new Error(message);
+            }
+            
+            return null;
+        }
+
+        /** 
+         *  @private 
+         *  Main internally used function to handle validation process.
+         */ 
+        private function processValidation(
+                            value:Object,
+                            suppressEvents:Boolean):ValidationResultEvent
+        {   
+            var resultEvent:ValidationResultEvent;
+            
+            if (_enabled)
+            {
+                var errorResults:Array = doValidation(value);
+
+                resultEvent = handleResults(errorResults);
+            }           
+            else
+            {
+                suppressEvents = true; // Don't send any events
+            }
+            
+            if (!suppressEvents)
+            {
+                dispatchEvent(resultEvent);
+            }
+
+            return resultEvent;
+        }
+
+        /**
+         *  Executes the validation logic of this validator, 
+         *  including validating that a missing or empty value
+         *  causes a validation error as defined by
+         *  the value of the <code>required</code> property.
+         *
+         *  <p>If you create a subclass of a validator class,
+         *  you must override this method. </p>
+         *
+         *  @param value Value to validate.
+         *
+         *  @return For an invalid result, an Array of ValidationResult objects,
+         *  with one ValidationResult object for each field examined
+         *  by the validator that failed validation.
+         *
+         *  @see mx.validators.ValidationResult
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function doValidation(value:Object):Array
+        {
+            var results:Array = [];
+            
+            var result:ValidationResult = validateRequired(value);
+            if (result)
+                results.push(result);
+                
+            return results;
+        }
+                
+        /**
+         *  @private 
+         *  Determines if an object is valid based on its
+         *  <code>required</code> property.
+         *  This is a convenience method for calling a validator from within a 
+         *  custom validation function. 
+         */
+        private function validateRequired(value:Object):ValidationResult
+        {
+            if (required)
+            {
+                var val:String = (value != null) ? String(value) : "";
+
+                val = trimString(val);
+
+                // If the string is empty and required is set to true
+                // then throw a requiredFieldError.
+                if (val.length == 0)
+                {
+                    return new ValidationResult(true, "", "requiredField",
+                                                requiredFieldError);                 
+                }
+            }
+            
+            return null;
+        }
+
+        /**
+         *  Returns a ValidationResultEvent from the Array of error results. 
+         *  Internally, this function takes the results from the 
+         *  <code>doValidation()</code> method and puts it into a ValidationResultEvent object. 
+         *  Subclasses, such as the RegExpValidator class, 
+         *  should override this function if they output a subclass
+         *  of ValidationResultEvent objects, such as the RegExpValidationResult objects, and 
+         *  needs to populate the object with additional information. You never
+         *  call this function directly, and you should rarely override it. 
+         *
+         *  @param errorResults Array of ValidationResult objects.
+         * 
+         *  @return The ValidationResultEvent returned by the <code>validate()</code> method. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        protected function handleResults(errorResults:Array):ValidationResultEvent
+        {
+            var resultEvent:ValidationResultEvent;
+            
+            if (errorResults.length > 0)
+            {
+                resultEvent =
+                    new ValidationResultEvent(ValidationResultEvent.INVALID);
+                resultEvent.results = errorResults;
+                
+                if (subFields.length > 0)
+                {
+                    var errorFields:Object = {};
+                    var subField:String;
+                    
+                    // Now we need to send valid results
+                    // for every subfield that didn't fail.
+                    var n:int;
+                    var i:int;
+                    
+                    n = errorResults.length;
+                    for (i = 0; i < n; i++)
+                    {
+                        subField = errorResults[i].subField;
+                        if (subField)
+                        {
+                            errorFields[subField] = true;
+                        }
+                    }
+                    
+                    n = subFields.length;
+                    for (i = 0; i < n; i++)
+                    {
+                        if (!errorFields[subFields[i]])
+                        {
+                            errorResults.push(new ValidationResult(false,subFields[i]));
+                        }
+                    }
+                }
+            }
+            else
+            {
+                resultEvent = new ValidationResultEvent(ValidationResultEvent.VALID);
+            }
+            
+            return resultEvent;
+        }
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Event handlers
+        //
+        //--------------------------------------------------------------------------
+        
+        /**
+         *  @private
+         */
+        private function triggerHandler(event:Event):void
+        {
+            validate();
+        }
+
+        /**
+         *  @private
+         */
+        private function resourceManager_changeHandler(event:Event):void
+        {
+            resourcesChanged();
+        }
+
+        private var document:Object;
+        
+        /**
+         *  @copy org.apache.flex.core.IDocument#setDocument()
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion FlexJS 0.0
+         */
+        public function setDocument(document:Object, id:String = null):void
+        {
+            this.document = document;
+        }
+
+    }   
+
+}
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidator.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidator.as
new file mode 100644
index 0000000..f074304
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidator.as
@@ -0,0 +1,807 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.flex.utils.validation
+{
+
+
+    // [ResourceBundle("validators")]
+
+    /**
+     *  The ZipCodeValidator class validates that a String
+     *  has the correct length and format for a five-digit ZIP code,
+     *  a five-digit+four-digit United States ZIP code, or Canadian postal code.
+     *  
+     *  @mxml
+     *
+     *  <p>The <code>&lt;mx:ZipCodeValidator&gt;</code> tag
+     *  inherits all of the tag attributes of its superclass,
+     *  and adds the following tag attributes:</p>
+     *  
+     *  <pre>
+     *  &lt;mx:ZipCodeValidator
+     *    allowedFormatChars=" -" 
+     *    domain="US Only | US or Canada | Canada Only"
+     *    invalidCharError="The ZIP code contains invalid characters." 
+     *    invalidDomainError="The domain parameter is invalid. It must be either 'US Only', 'Canada Only', or 'US or Canada'." 
+     *    wrongCAFormatError="The Canadian postal code must be formatted 'A1B 2C3'." 
+     *    wrongLengthError="The ZIP code must be 5 digits or 5+4 digits." 
+     *    wrongUSFormatError="The ZIP+4 code must be formatted '12345-6789'." 
+     *  /&gt;
+     *  </pre>
+     *  
+     *  @see mx.validators.ZipCodeValidatorDomainType
+     * 
+     *  @includeExample examples/ZipCodeValidatorExample.mxml
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public class ZipCodeValidator extends Validator
+    {
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class constants
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  @private
+         */
+        private static const DOMAIN_US:uint = 1;
+        
+        /**
+         *  @private
+         */
+        private static const DOMAIN_US_OR_CANADA:uint = 2;
+        
+        /**
+         * @private 
+         */
+        private static const DOMAIN_CANADA:uint = 3;   
+
+        //--------------------------------------------------------------------------
+        //
+        //  Class methods
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Convenience method for calling a validator.
+         *  Each of the standard Flex validators has a similar convenience method.
+         *
+         *  @param validator The ZipCodeValidator instance.
+         *
+         *  @param value A field to validate.
+         *
+         *  @param baseField Text representation of the subfield
+         *  specified in the <code>value</code> parameter.
+         *  For example, if the <code>value</code> parameter specifies value.zipCode,
+         *  the <code>baseField</code> value is <code>"zipCode"</code>.
+         *
+         *  @return An Array of ValidationResult objects, with one ValidationResult 
+         *  object for each field examined by the validator. 
+         *
+         *  @see mx.validators.ValidationResult
+         *
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public static function validateZipCode(validator:ZipCodeValidator,
+                                            value:Object,
+                                            baseField:String):Array
+        {
+            var results:Array = [];
+        
+            // Resource-backed properties of the validator.
+            var allowedFormatChars:String = validator.allowedFormatChars;
+            var domain:String = validator.domain;
+
+            var resourceManager:IResourceManager = ResourceManager.getInstance();
+
+            var zip:String = String(value);
+            var len:int = zip.length;
+            
+            var domainType:uint = DOMAIN_US;
+            switch (domain)
+            {
+                case ZipCodeValidatorDomainType.US_OR_CANADA:
+                {
+                    domainType = DOMAIN_US_OR_CANADA;
+                    break;
+                }
+                
+                case ZipCodeValidatorDomainType.US_ONLY:
+                {
+                    domainType = DOMAIN_US;
+                    break;
+                }
+                
+                case ZipCodeValidatorDomainType.CANADA_ONLY:
+                {
+                    domainType = DOMAIN_CANADA;
+                    break;
+                }
+                
+                default:
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidDomain",
+                        validator.invalidDomainError));
+                    return results;
+                }
+                
+            }
+            
+            var n:int;
+            var i:int;
+            var c:String;
+            
+            // Make sure localAllowedFormatChars contains no numbers or letters.
+            n = allowedFormatChars.length;
+            for (i = 0; i < n; i++)
+            {
+                c = allowedFormatChars.charAt(i);
+                if (DECIMAL_DIGITS.indexOf(c) != -1 ||
+                    ROMAN_LETTERS.indexOf(c) != -1)
+                {
+                    var message:String = resourceManager.getString(
+                        "validators", "invalidFormatCharsZCV");
+                    throw new Error(message);
+                }
+            }
+
+            // Now start checking the ZIP code.
+            // At present, only US and Canadian ZIP codes are supported.
+            // As a result, the easiest thing to check first
+            // to determine the domain is the length.
+            // A length of 5 or 10 means a US ZIP code
+            // and a length of 6 or 7 means a Canadian ZIP.
+            // If more countries are supported in the future, it may make sense
+            // to check other conditions first depending on the domain specified
+            // and all the possible ZIP code formats for that domain.
+            // For now, this approach makes the most sense.
+
+            // Make sure there are no invalid characters in the ZIP.
+            for (i = 0; i < len; i++)
+            {
+                c = zip.charAt(i);
+                
+                if (ROMAN_LETTERS.indexOf(c) == -1 &&
+                    DECIMAL_DIGITS.indexOf(c) == -1 &&
+                    allowedFormatChars.indexOf(c) == -1)
+                {
+                    results.push(new ValidationResult(
+                        true, baseField, "invalidChar",
+                        validator.invalidCharError));
+                    return results;
+                }
+            }
+            
+            // Find out if the ZIP code contains any letters.
+            var containsLetters:Boolean = false;
+            for (i = 0; i < len; i++)
+            {
+                if (ROMAN_LETTERS.indexOf(zip.charAt(i)) != -1)
+                {
+                    containsLetters = true;
+                    break;
+                }
+            }
+            
+            // do an initial check on the length
+            if ((len < 5 || len > 10) || (len == 8) || 
+                (!containsLetters && (len == 6 || len == 7)))
+            {
+                // it's the wrong length for either a US or Canadian zip
+                results.push(new ValidationResult(
+                    true, baseField, "wrongLength",
+                    validator.wrongLengthError));
+                return results;
+            }
+            
+            // if we got this far, we're doing good so far
+            switch (domainType)
+            {
+                case DOMAIN_US:
+                {
+                    if (validator.validateUSCode(zip, containsLetters) == false)
+                    {
+                        results.push(new ValidationResult(
+                                true, baseField, "wrongUSFormat",
+                                validator.wrongUSFormatError));
+                        return results;
+                    }
+                    break;
+                }
+                
+                case DOMAIN_CANADA:
+                {
+                    if (validator.validateCACode(zip, containsLetters) == false)
+                    {
+                        results.push(new ValidationResult(
+                            true, baseField, "wrongCAFormat",
+                            validator.wrongCAFormatError));
+                        return results;
+                    }
+                    break;
+                }
+                
+                case DOMAIN_US_OR_CANADA:
+                {
+                    
+                    var valid:Boolean = true;
+                    var validationResult:ValidationResult;
+                    
+                    if (len == 5 || len == 9 || len == 10) // US
+                    {
+                        if (validator.validateUSCode(zip, containsLetters) == false)
+                        {
+                            validationResult = new ValidationResult(
+                                true, baseField, "wrongUSFormat",
+                                validator.wrongUSFormatError);
+                                
+                            valid = false;
+                        }
+                    }
+                    else // CA
+                    {
+                        if (validator.validateCACode(zip, containsLetters) == false)
+                        {
+                            validationResult = new ValidationResult(
+                                true, baseField, "wrongCAFormat",
+                                validator.wrongCAFormatError);
+                        
+                            valid = false;
+                        }
+                    }
+                    
+                    if (!valid)
+                    {         
+                        results.push(validationResult);
+                        return results;
+                    }
+                    break;
+                }
+            }
+
+            return results;
+        }
+        
+        /**
+         *  @private
+         */
+        private function validateUSCode (zip:String, containsLetters:Boolean):Boolean
+        {
+            var len:int = zip.length;
+                    
+            if (containsLetters) 
+            {
+                return false;
+            }
+            
+            // Make sure the first 5 characters are all digits.
+            var i:uint;
+            for (i = 0; i < 5; i++)
+            {
+                if (DECIMAL_DIGITS.indexOf(zip.charAt(i)) == -1)
+                {
+                    return false;
+                }
+            }
+            
+            if (len == 9 || len == 10)
+            {
+                if (len == 10)
+                {
+                    // Make sure the 6th character
+                    // is an allowed formatting character.
+                    if (allowedFormatChars.indexOf(zip.charAt(5)) == -1)
+                    {
+                        return false;
+                    }
+                    i++;
+                }
+                
+                // Make sure the remaining 4 characters are digits.
+                for (; i < len; i++)
+                {
+                    if (DECIMAL_DIGITS.indexOf(zip.charAt(i)) == -1)
+                    {
+                        return false;
+                    }
+                }
+            }
+            
+            return true;
+        }
+        
+        /**
+         *  @private
+         */
+        private function validateCACode (zip:String, containsLetters:Boolean):Boolean
+        {
+            var len:int = zip.length;
+            
+            // check the basics
+            if (!containsLetters)
+            {
+                return false;
+            }
+            
+            var i:uint = 0;
+
+            // Make sure the zip is in the form 'ldlfdld'
+            // where l is a letter, d is a digit,
+            // and f is an allowed formatting character.
+            if (ROMAN_LETTERS.indexOf(zip.charAt(i++)) == -1 ||
+                DECIMAL_DIGITS.indexOf(zip.charAt(i++)) == -1 ||
+                ROMAN_LETTERS.indexOf(zip.charAt(i++)) == -1)
+            {
+                return false;
+            }
+            
+            if (len == 7 &&
+                allowedFormatChars.indexOf(zip.charAt(i++)) == -1)
+            {
+                return false;
+            }
+            
+            if (DECIMAL_DIGITS.indexOf(zip.charAt(i++)) == -1 ||
+                ROMAN_LETTERS.indexOf(zip.charAt(i++)) == -1 ||
+                DECIMAL_DIGITS.indexOf(zip.charAt(i++)) == -1)
+            {
+                return false;
+            }
+            
+            return true;
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+
+        /**
+         *  Constructor.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function ZipCodeValidator()
+        {
+            super();
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  allowedFormatChars
+        //----------------------------------
+
+        /**
+         *  @private
+         */
+        private var _allowedFormatChars:String;
+
+        /**
+         *  @private
+         */
+        private var allowedFormatCharsOverride:String;
+        
+        [Inspectable(category="General", defaultValue="null")]
+
+        /** 
+         *  The set of formatting characters allowed in the ZIP code.
+         *  This can not have digits or alphabets [a-z A-Z].
+         *
+         *  @default " -". 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get allowedFormatChars():String
+        {
+            return _allowedFormatChars;
+        }
+
+        /**
+         *  @private
+         */
+        public function set allowedFormatChars(value:String):void
+        {
+            if (value != null)
+            {
+                for (var i:int = 0; i < value.length; i++)
+                {
+                    var c:String = value.charAt(i);
+                    if (DECIMAL_DIGITS.indexOf(c) != -1 ||
+                        ROMAN_LETTERS.indexOf(c) != -1)
+                    {
+                        var message:String = resourceManager.getString(
+                            "validators", "invalidFormatCharsZCV");
+                        throw new Error(message);
+                    }
+                }
+            }
+
+            allowedFormatCharsOverride = value;
+
+            _allowedFormatChars = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators",
+                                    "zipCodeValidatorAllowedFormatChars");
+        }
+
+        //----------------------------------
+        //  domain
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the domain property.
+         */
+        private var _domain:String;
+        
+        /**
+         *  @private
+         */
+        private var domainOverride:String;
+
+        [Inspectable(category="General", defaultValue="null")]
+
+        /** 
+         *  Type of ZIP code to check.
+         *  In MXML, valid values are <code>"US or Canada"</code>, 
+         *  <code>"US Only"</code> and <code>"Canada Only"</code>.
+         *
+         *  <p>In ActionScript, you can use the following constants to set this property: 
+         *  <code>ZipCodeValidatorDomainType.US_ONLY</code>, 
+         *  <code>ZipCodeValidatorDomainType.US_OR_CANADA</code>, or
+         *  <code>ZipCodeValidatorDomainType.CANADA_ONLY</code>.</p>
+         *
+         *  @default ZipCodeValidatorDomainType.US_ONLY
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get domain():String
+        {
+            return _domain;
+        }
+
+        /**
+         *  @private
+         */
+        public function set domain(value:String):void
+        {
+            domainOverride = value;
+
+            _domain = value != null ?
+                    value :
+                    resourceManager.getString(
+                        "validators", "zipCodeValidatorDomain");
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Properties: Errors
+        //
+        //--------------------------------------------------------------------------
+
+        //----------------------------------
+        //  invalidCharError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the invalidCharError property.
+         */
+        private var _invalidCharError:String;
+        
+        /**
+         *  @private
+         */
+        private var invalidCharErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when the ZIP code contains invalid characters.
+         *
+         *  @default "The ZIP code contains invalid characters."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get invalidCharError():String
+        {
+            return _invalidCharError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set invalidCharError(value:String):void
+        {
+            invalidCharErrorOverride = value;
+
+            _invalidCharError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "invalidCharErrorZCV");
+        }
+
+        //----------------------------------
+        //  invalidDomainError
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the invalidDomainError property.
+         */
+        private var _invalidDomainError:String;
+        
+        /**
+         *  @private
+         */
+        private var invalidDomainErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message when the <code>domain</code> property contains an invalid value.
+         *
+         *  @default "The domain parameter is invalid. It must be either 'US Only' or 'US or Canada'."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get invalidDomainError():String
+        {
+            return _invalidDomainError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set invalidDomainError(value:String):void
+        {
+            invalidDomainErrorOverride = value;
+
+            _invalidDomainError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "invalidDomainErrorZCV");
+        }
+        
+        //----------------------------------
+        //  wrongCAFormatError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the wrongCAFormatError property.
+         */
+        private var _wrongCAFormatError:String;
+        
+        /**
+         *  @private
+         */
+        private var wrongCAFormatErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message for an invalid Canadian postal code.
+         *
+         *  @default "The Canadian postal code must be formatted 'A1B 2C3'."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get wrongCAFormatError():String
+        {
+            return _wrongCAFormatError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set wrongCAFormatError(value:String):void
+        {
+            wrongCAFormatErrorOverride = value;
+
+            _wrongCAFormatError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "wrongCAFormatError");
+        }
+        
+        //----------------------------------
+        //  wrongLengthError
+        //----------------------------------
+        
+        /**
+         *  @private
+         *  Storage for the wrongLengthError property.
+         */
+        private var _wrongLengthError:String;
+        
+        /**
+         *  @private
+         */
+        private var wrongLengthErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message for an invalid US ZIP code.
+         *
+         *  @default "The ZIP code must be 5 digits or 5+4 digits."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get wrongLengthError():String
+        {
+            return _wrongLengthError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set wrongLengthError(value:String):void
+        {
+            wrongLengthErrorOverride = value;
+
+            _wrongLengthError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "wrongLengthErrorZCV");
+        }
+        
+        //----------------------------------
+        //  wrongUSFormatError
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the wrongUSFormatError property.
+         */
+        private var _wrongUSFormatError:String;
+        
+        /**
+         *  @private
+         */
+        private var wrongUSFormatErrorOverride:String;
+
+        [Inspectable(category="Errors", defaultValue="null")]
+
+        /** 
+         *  Error message for an incorrectly formatted ZIP code.
+         *
+         *  @default "The ZIP+4 code must be formatted '12345-6789'."
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get wrongUSFormatError():String
+        {
+            return _wrongUSFormatError;
+        }
+
+        /**
+         *  @private
+         */
+        public function set wrongUSFormatError(value:String):void
+        {
+            wrongUSFormatErrorOverride = value;
+
+            _wrongUSFormatError = value != null ?
+                                value :
+                                resourceManager.getString(
+                                    "validators", "wrongUSFormatError");
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Overridden methods
+        //
+        //--------------------------------------------------------------------------
+    
+        /**
+         *  @private    
+         */
+        override protected function resourcesChanged():void
+        {
+            super.resourcesChanged();
+
+            allowedFormatChars = allowedFormatCharsOverride;
+            domain = domainOverride;
+
+            invalidDomainError = invalidDomainErrorOverride;
+            invalidCharError = invalidCharErrorOverride;
+            wrongCAFormatError = wrongCAFormatErrorOverride;
+            wrongLengthError = wrongLengthErrorOverride;
+            wrongUSFormatError = wrongUSFormatErrorOverride;    
+        }
+
+        /**
+         *  Override of the base class <code>doValidation()</code> method
+         *  to validate a ZIP code.
+         *
+         *  <p>You do not call this method directly;
+         *  Flex calls it as part of performing a validation.
+         *  If you create a custom Validator class, you must implement this method. </p>
+         *
+         *  @param value Object to validate.
+         *
+         *  @return An Array of ValidationResult objects, with one ValidationResult 
+         *  object for each field examined by the validator. 
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        override protected function doValidation(value:Object):Array
+        {
+            var results:Array = super.doValidation(value);
+            
+            // Return if there are errors
+            // or if the required property is set to false and length is 0.
+            var val:String = value ? String(value) : "";
+            if (results.length > 0 || ((val.length == 0) && !required))
+                return results;
+            else
+                return ZipCodeValidator.validateZipCode(this, value, null);
+        }
+    }
+
+}
+
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidatorDomainType.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidatorDomainType.as
new file mode 100644
index 0000000..ce13491
--- /dev/null
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/validation/ZipCodeValidatorDomainType.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 org.apache.flex.utils.validation
+{
+
+/**
+ *  The ZipCodeValidatorDomainType class defines the values 
+ *  for the <code>domain</code> property of the ZipCodeValidator class,
+ *  which you use to specify the type of ZIP code to validate.
+ *
+ *  @see mx.validators.ZipCodeValidator
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public final class ZipCodeValidatorDomainType
+{
+
+	//--------------------------------------------------------------------------
+	//
+	//  Class constants
+	//
+	//--------------------------------------------------------------------------
+	
+	/**
+	 *  Specifies to validate a United States or Canadian ZIP code.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const US_OR_CANADA:String = "US or Canada";
+	
+	/**
+	 *  Specifies to validate a United States ZIP code.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const US_ONLY:String = "US Only";
+	
+	/**
+	 *  Specifies to validate a Canadian ZIP code.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const CANADA_ONLY:String = "Canada Only";
+}
+
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@royale.apache.org" <co...@royale.apache.org>.