http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/CompareBitmap.as
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/CompareBitmap.as 
b/mustella/src/main/flex/CompareBitmap.as
new file mode 100644
index 0000000..52c4df8
--- /dev/null
+++ b/mustella/src/main/flex/CompareBitmap.as
@@ -0,0 +1,1603 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT 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  { 
+
+import flash.display.BitmapData;
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.IBitmapDrawable;
+import flash.display.Loader;
+import flash.events.Event;
+import flash.events.IOErrorEvent;
+import flash.events.SecurityErrorEvent;
+import flash.events.StatusEvent;
+import flash.geom.ColorTransform;
+import flash.geom.Matrix;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+import flash.net.LocalConnection;
+import flash.net.URLLoader;
+import flash.net.URLRequest;
+import flash.text.TextField;
+import flash.text.TextFormat;
+import flash.text.engine.ContentElement;
+import flash.text.engine.TextBlock;
+import flash.text.engine.TextLine;
+import flash.utils.ByteArray;
+import flash.utils.getQualifiedClassName;
+
+import mx.core.IChildList;
+import mx.core.IRawChildrenContainer;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+/**
+*  Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ *  The test step that compares a bitmap against a reference bitmap
+ *  MXML attributes:
+ *  target
+ *  url
+ *  timeout (optional);
+ *  maxColorVariance
+ *  numColorVariances
+ *  waitTarget Do Not Use
+ *  waitEvent Do Not Use
+ *  stageText - placeholder, does nothing
+ *
+ *
+ *  Do not set waitEvent or waitTarget on this step.  They are set internally
+ *  to manage the loading of the reference bitmap.  The step prior to this
+ *  step must wait for the system to synch up.
+ *  
+ *  CompareBitmap will parse the url attribute for $testID, replacing with the 
current testID
+ */
+public class CompareBitmap extends Assert
+{ 
+       public static var useRemoteDiffer:Boolean = false;
+       
+       private static var identityMatrix:String = new Matrix().toString();
+       private static var identityColorTransform:String = new 
ColorTransform().toString();
+       
+       public static var DEFAULT_MAX_COLOR_VARIANCE:int = 0;
+       public static var DEFAULT_NUM_COLOR_VARIANCES:int = 0;
+       public static var DEFAULT_MAX_MATRIX_VARIANCE:Number = 0.1;
+
+       // This is the default property.
+       public var conditionalValues:Vector.<ConditionalValue> = null;
+       
+       /**
+        *  The url of the file to read. If UnitTester.createBitmapReferences = 
true,
+        *  the url to store the bitmap
+        */
+       public var url:String;
+
+       
+       /**
+        *  placeHolder for stageText, does nothing
+        */
+       public var stageText:String;
+
+       private var _maxColorVariance:int = 0;
+       /**
+        *  The maximum color variation allowed in a bitmap compare.
+        *  Some machines render slightly differently and thus we have
+        *  to allow the the compare to not be exact.
+        */
+       public function get maxColorVariance():int
+       {
+               if (_maxColorVariance)
+                       return _maxColorVariance;
+
+               return DEFAULT_MAX_COLOR_VARIANCE;
+       }
+       public function set maxColorVariance(value:int):void
+       {
+               _maxColorVariance = value;
+       }
+
+       private var _ignoreMaxColorVariance:Boolean = false;
+       
+       /**
+        * Sometimes you have numColorVariance defined and you don't really 
care by how much the pixel really differ.
+        * as long as the number of mismatching pixels is &lt;= numColorVariance
+        * Setting this to true will skip the maxColorVariance check (and take 
the guess work out of picture). default is false
+        */
+       public function get ignoreMaxColorVariance():Boolean
+       {
+               return _ignoreMaxColorVariance;
+       }
+       
+       public function set ignoreMaxColorVariance(value:Boolean):void
+       {
+               _ignoreMaxColorVariance = value;
+       }
+
+
+       private var _numColorVariances:int = 0;
+       /**
+        *  The number of color variation allowed in a bitmap compare.
+        *  Some machines render slightly differently and thus we have
+        *  to allow the the compare to not be exact.
+        */
+       public function get numColorVariances():int
+       {
+               if (_numColorVariances)
+                       return _numColorVariances;
+
+               return DEFAULT_NUM_COLOR_VARIANCES;
+       }
+       public function set numColorVariances(value:int):void
+       {
+               _numColorVariances = value;
+       }
+
+       private var _maxMatrixVariance:Number = 0.1;
+       /**
+        *  The maximum color variation allowed in a bitmap compare.
+        *  Some machines render slightly differently and thus we have
+        *  to allow the the compare to not be exact.
+        */
+       public function get maxMatrixVariance():Number
+       {
+               if (_maxMatrixVariance)
+                       return _maxMatrixVariance;
+               
+               return DEFAULT_MAX_MATRIX_VARIANCE;
+       }
+       public function set maxMatrixVariance(value:Number):void
+       {
+               _maxMatrixVariance = value;
+       }
+
+       /**
+        *  Suffix to add to the file being written out (the case of a compare 
failure)
+        */
+       public static var fileSuffix:String = "";
+
+       private var reader:Loader;
+       private var xmlreader:URLLoader;
+       private var writer:URLLoader;
+
+       private static var connection:LocalConnection;
+       private static var commandconnection:LocalConnection;
+       
+       private var baselineMissing:Boolean = false;
+       private var baselineMissingMessage:String = "Baseline image could not 
be read.  Created image file as a .bad.png.";
+       private var baselineMissingMessageFail:String = "Baseline image could 
not be read, and we failed to write the .bad.png";
+       
+       private function statusHandler(event:Event):void
+       {
+       }
+
+       /**
+        *  Constructor
+        */
+       public function CompareBitmap() 
+       { 
+               if (useRemoteDiffer)
+               {
+                       if (!connection)
+                       {
+                               connection = new LocalConnection();
+                               connection.allowDomain("*");
+                               connection.addEventListener(StatusEvent.STATUS, 
statusHandler);
+       
+                               commandconnection = new LocalConnection();
+                               commandconnection.allowDomain("*");
+       
+                               try
+                               {
+                                       
commandconnection.connect("_ImageDifferCommands");
+                               }
+                               catch (e:Error)
+                               {
+                                       trace("connection failed");
+                               }
+                       }
+               }
+       }
+
+       override public function execute(root:DisplayObject, 
context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+       {
+               var cv:ConditionalValue = null;
+               var configID:String = null;
+               
+               // Use MultiResult to determine the proper URL.
+               if(conditionalValues){
+                       cv = new MultiResult().chooseCV(conditionalValues);
+                       if(cv){
+                               // This way, we use CompareBitmap's url 
(directory) if the CV's is not set.
+                               if( cv.url != null ){
+                                       url = cv.url;
+                               }
+                       }
+               }else{
+                       // We do not have ConditionalValues.  If the current 
config is unknown, it is probably
+                       // a desktop AIR run, and we should just let things 
take the course they always have.
+                       // If a config is known, then we want to use the new 
config ID suffix mechanism later.
+                       configID = TargetConfigurations.getTargetConfigID( 
UnitTester.cv );
+                       if( configID ){
+                               trace( "CompareBitmap: No ConditionalValues 
found.  configID is " + configID.toString() );
+                       }else{
+                               trace( "CompareBitmap: No ConditionalValues 
found.  configID is " + configID );
+                       }
+               }
+
+               if( url == null ){
+                       if( cv == null ){
+                               throw new Error("Found no url on the 
CompareBitmap for test case " + testCase.testID);
+                       }else{
+                               throw new Error("Found no url on the 
ConditionalValue for test case " + testCase.testID + ", ConditionalValue: " + 
cv.toString());
+                       }
+               }
+
+               // See if url ends with .png.  If not, create a file name.
+               if( url.lastIndexOf( ".png" ) != url.length - 4 ){
+                       
+                       // Add a path separator if necessary.
+                       if( url.lastIndexOf( "/" ) != url.length - 1 ){
+                               url += "/";
+                       }               
+
+                       // Decide on a file name.
+                       if( conditionalValues ){
+                               // If we ended up with a matching CV, ask it to 
create a file name.
+                               // Otherwise, go with the test ID.
+                               // Keep this path alive until (if ever) 
ConditionalValues in CompareBitmaps have all been removed.
+                               if(cv){
+                                       trace( "CompareBitmap: Asking the 
ConditionalValue to create the file name." );
+                                       url += cv.createFilename( 
testCase.testID );
+                               } else {
+                                       trace( "CompareBitmap: Creating the 
file name from the testID." );
+                                       url += testCase.testID + ".png";
+                               }
+                       }else if( configID ){
+                               // We have no ConditionalValues and we're 
running a known config,
+                               // so use the config id in the suffix.
+                               trace( "CompareBitmap: Creating the file name 
from the configID." );
+                               url += testCase.testID + "@" + configID + 
".png";
+                       }else{
+                               trace( "There is no file name, there are no 
Conditional Values, and there is no configID.  There's not much we can do now, 
is there?" );
+                       }
+               }
+               
+               if (url != null && url.indexOf ("$testID") != -1) { 
+                       trace ("SAW THE REF, I'll plug it");
+                       url = url.replace ("$testID", UnitTester.currentTestID);
+                       trace ("result 2: " + url);
+               }
+
+               if (url == null)
+                       trace ("URL was null at execute time");
+
+               if (commandconnection)
+                       commandconnection.client = this;
+
+               var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+               if (!actualTarget)
+               {
+                       testResult.doFail("Target " + target + " not found");
+                       return true;
+               }
+
+               if (stageText)
+                       updateStageTexts(actualTarget);
+               
+               this.root = root;
+               this.context = context;
+               this.testResult = testResult;
+
+               if (UnitTester.createBitmapReferences)
+               {
+                       if (UnitTester.checkEmbeddedFonts)
+                       {
+                               if (!checkEmbeddedFonts(actualTarget))
+                               {
+                                       testResult.doFail ("Target " + 
actualTarget + " is using non-embedded or advanced anti-aliased fonts"); 
+                                       return true;
+                               }
+                       }
+
+                       writeBaselines(actualTarget);
+                       return false;
+               }
+               else
+               {
+                       readPNG();
+                       return false;
+               }
+
+       }
+
+       // there are a few mobile tests that use StageText in the bitmaps
+       // which are TextFields in the emulator.  This makes them use
+       // embedded fonts to get consistency across platforms.
+       private function updateStageTexts(target:DisplayObject):void
+       {
+               var doc:DisplayObjectContainer = target as 
DisplayObjectContainer;
+               var tf:Object;
+               tf = findTextWidget(doc);
+               if (tf)
+               {
+                       var n:int = target.stage.numChildren;
+                       for (var i:int = 0; i < n; i++)
+                       {
+                               var stf:TextField = target.stage.getChildAt(i) 
as TextField;
+                               if (stf)
+                               {
+                                       var stfm:TextFormat = new 
TextFormat(tf.getStyle("fontFamily"),
+                                                                               
                                        tf.getStyle("fontSize"),
+                                                                               
                                        tf.getStyle("color"),
+                                                                               
                                        tf.getStyle("fontWeight") == "bold",
+                                                                               
                                        tf.getStyle("fontStyle") == "italic"
+                                                                               
                                        );
+                                       stf.defaultTextFormat = stfm;
+                                       stf.embedFonts = true;
+                               }
+                       }
+               }
+       }
+       
+       private function findTextWidget(doc:DisplayObjectContainer):Object
+       {
+               if (!doc) return null;
+               var n:int = doc.numChildren;
+               for (var i:int = 0; i < n; i++)
+               {
+                       var child:DisplayObject = doc.getChildAt(i);
+                       var className:String = getQualifiedClassName(child);
+                       if (className.indexOf("StyleableStageText") > -1)
+                               return child;
+                       else if (child is DisplayObjectContainer)
+                       {
+                               var tf:Object = findTextWidget(child as 
DisplayObjectContainer);
+                               if (tf) return tf;
+                       }
+               }
+               return null;
+       }
+       
+       private function getTargetSize(target:DisplayObject):Point
+       {
+               var width:Number;
+               var height:Number;
+
+        try
+        {  
+            width = target["getUnscaledWidth"]() * Math.abs(target.scaleX) * 
target.root.scaleX;
+            height = target["getUnscaledHeight"]() * Math.abs(target.scaleY) * 
target.root.scaleY;
+        }
+        catch(e:ReferenceError)
+        {
+            width = target.width * target.root.scaleX;
+            height = target.height * target.root.scaleY;
+        }
+        trace("getTargetSize: height: ", target.height);
+        trace("getTargetSize: root.height: ", target.root.height);
+        trace("getTargetSize: stageHeight: ", target.stage.stageHeight);
+        try {
+        trace("getTargetSize: loaderInfo.height: ", target.loaderInfo.height);
+        } catch (e:Error) {};
+        
+               return new Point(width, height);
+       }
+
+       // Given a displayObject, sets up the screenBits.
+       private function getScreenBits(target:DisplayObject):void{
+               try 
+               {
+                       var targetSize:Point = getTargetSize(target);
+                       var stagePt:Point = target.localToGlobal(new Point(0, 
0));
+            var altPt:Point = target.localToGlobal(targetSize);
+            stagePt.x = Math.min(stagePt.x, altPt.x);
+            stagePt.y = Math.min(stagePt.y, altPt.y);
+                       screenBits = new BitmapData(targetSize.x, targetSize.y);
+                       screenBits.draw(target.stage, new Matrix(1, 0, 0, 1, 
-stagePt.x, -stagePt.y));
+               }
+               catch (se:SecurityError)
+               {
+                       UnitTester.hideSandboxes();
+                       try
+                       {
+                               screenBits.draw(target.stage, new Matrix(1, 0, 
0, 1, -stagePt.x, -stagePt.y));
+                       }
+                       catch (se2:Error)
+                       {
+                               try 
+                               {
+                                       // if we got a security error and ended 
up here, assume we're in the
+                                       // genericLoader loads us scenario
+                                       screenBits.draw(target.root, new 
Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+                               }
+                               catch (se3:Error)
+                               {
+                               }
+                       }
+                       UnitTester.showSandboxes();
+                       var sb:Array = UnitTester.getSandboxBitmaps();
+                       var n:int = sb.length;
+                       for (var i:int = 0; i < n; i++)
+                       {
+                               mergeSandboxBitmap(target, stagePt, screenBits, 
sb[i]);
+                       }
+               }
+               catch (e:Error)
+               {
+                       testResult.doFail (e.getStackTrace());  
+               }
+       }
+
+       private var MAX_LC:int = 12000;
+       private var screenBits:BitmapData;
+       private var baselineBits:BitmapData;
+
+       private var compareVal:Object;
+       
+       public function comparePNG(target:DisplayObject):Boolean 
+       { 
+               if (UnitTester.checkEmbeddedFonts)
+               {
+                       if (!checkEmbeddedFonts(target))
+                       {
+                               testResult.doFail ("Target " + target + " is 
using non-embedded or advanced anti-aliased fonts");       
+                               return true;
+                       }
+               }
+
+               try {
+                       if (!reader.content)
+                       {
+                               testResult.doFail ("baseline image not 
available");
+                               return true;
+                       }
+               } catch( e:Error ) {
+                       testResult.doFail ("CompareBitmap BIG FAIL! Content 
reader is null!");
+                       return true;
+               }
+               
+               getScreenBits(target);
+
+               try
+               {
+                       baselineBits = new BitmapData(reader.content.width, 
reader.content.height);
+                       baselineBits.draw(reader.content, new Matrix());
+
+                       compareVal = baselineBits.compare (screenBits);
+               
+                       if (compareVal is BitmapData && numColorVariances)
+                               compareVal = compareWithVariances(compareVal as 
BitmapData)
+
+                       if (compareVal != 0)
+                       {
+                               trace ("compare returned" + compareVal);
+                               
+                               var req:URLRequest = new URLRequest();
+                               if (UnitTester.isApollo) 
+                               {
+                                       req.url = 
encodeURI2(CompareBitmap.adjustPath (url));
+                               } 
+                               else
+                               {
+                                       req.url = url;
+                                       var base:String = 
normalizeURL(context.application.url);
+                                       base = base.substring(0, 
base.lastIndexOf("/"));
+                                       while (req.url.indexOf("../") == 0)
+                                       {
+                                               base = base.substring(0, 
base.lastIndexOf("/"));
+                                               req.url = req.url.substring(3);
+                                       }
+                                       
+                                       req.url = encodeURI2(base + "/" + 
req.url);
+                               }
+                               
+                               req.url += ".xml";
+                               xmlreader = new URLLoader();
+                               xmlreader.addEventListener(Event.COMPLETE, 
readXMLCompleteHandler);
+                               
xmlreader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, readErrorHandler);
+                               
xmlreader.addEventListener(IOErrorEvent.IO_ERROR, readXMLIOErrorHandler);
+                               xmlreader.load (req);   
+                               return false;
+                       }
+               }
+               catch (e:Error) 
+               { 
+                       testResult.doFail (e.getStackTrace());  
+               }
+               return true;
+       }
+               
+       private function readXMLCompleteHandler(event:Event):void
+       {
+               var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+               var s:String = getDisplayListXML(actualTarget).toXMLString();
+               var t:String = xmlreader.data;
+               s = s.replace(/\r/g, "");
+               t = t.replace(/\r/g, "");               
+               if (s !== t && xmldiffer(s, t))
+               {
+                       testResult.doFail ("compare returned" + compareVal, 
absolutePathResult(url) + ".bad.png");
+                       
+                       if (useRemoteDiffer)
+                       {
+                               sendImagesToDiffer();
+                       } 
+                       else if (fileSuffix != "") 
+                       { 
+                               writeBaselines (actualTarget);
+                       }
+               }
+               else
+                       stepComplete();
+       }
+       
+       private function readXMLIOErrorHandler(event:Event):void
+       {
+               if (useRemoteDiffer)
+               {
+                       sendImagesToDiffer();
+               } 
+               else if (fileSuffix != "") 
+               { 
+                       testResult.doFail ("compare returned" + compareVal, 
absolutePathResult(url) + ".bad.png");
+                       var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+                       writePNG (actualTarget);
+               }       
+       }
+       
+       private function mergeSandboxBitmap(target:DisplayObject, pt:Point, 
bm:BitmapData, obj:Object):void
+       {
+               var targetSize:Point = getTargetSize(target);
+               var sbm:BitmapData = new BitmapData(obj.width, obj.height);
+               var srcRect:Rectangle = new Rectangle(0, 0, obj.width, 
obj.height);
+               sbm.setPixels(srcRect, obj.bits);
+               var targetRect:Rectangle = new Rectangle(pt.x, pt.y, 
targetSize.x, targetSize.y);
+               var sbRect:Rectangle = new Rectangle(obj.x, obj.y, obj.width, 
obj.height);
+               var area:Rectangle = targetRect.intersection(sbRect);
+               if (area)
+                       bm.copyPixels(sbm, srcRect, 
target.globalToLocal(area.topLeft));
+       }
+
+       private function sendImagesToDiffer():void
+       {
+               UnitTester.callback = stringifyScreen;
+       }
+
+       private var ba:ByteArray;
+       private function stringifyScreen():void
+       {
+               ba = screenBits.getPixels(screenBits.rect);
+               ba.position = 0;
+               connection.send("_ImageDiffer", "startScreenData", 
screenBits.width, screenBits.height, ba.length, UnitTester.currentTestID, 
UnitTester.currentScript);
+               UnitTester.callback = sendScreen;
+       }
+
+       private function sendScreen():void
+       {
+               if (ba.position + MAX_LC < ba.length)
+               {
+                       connection.send("_ImageDiffer", "addScreenData", 
stringify(ba));
+                       UnitTester.callback = sendScreen;
+               }
+               else
+               {
+                       connection.send("_ImageDiffer", "addScreenData", 
stringify(ba));
+                       UnitTester.callback = stringifyBase;
+               }
+       }
+
+       private function stringifyBase():void
+       {
+               ba = baselineBits.getPixels(baselineBits.rect);
+               ba.position = 0;
+               connection.send("_ImageDiffer", "startBaseData", 
baselineBits.width, baselineBits.height, ba.length);
+               UnitTester.callback = sendBase;
+       }
+
+       private function sendBase():void
+       {
+               if (ba.position + MAX_LC < ba.length)
+               {
+                       connection.send("_ImageDiffer", "addBaseData", 
stringify(ba));
+                       UnitTester.callback = sendBase;
+               }
+               else
+               {
+                       connection.send("_ImageDiffer", "addBaseData", 
stringify(ba));
+                       connection.send("_ImageDiffer", "compareBitmaps");
+               }
+       }
+
+       private function stringify(ba:ByteArray):String
+       {
+               var n:int = Math.min(ba.length - ba.position, MAX_LC);
+               var arr:Array = [];
+               for (var i:int = 0; i < n; i++)
+               {
+                       var b:int = ba.readUnsignedByte();
+                       arr.push(b.toString(16))
+               }
+               return arr.toString();
+       }
+
+       private function readCompleteHandler(event:Event):void
+       {
+               var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+               if (comparePNG(actualTarget))
+                       preStepComplete();
+       }
+
+       private function readErrorHandler(event:Event):void
+       {
+               var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+               getScreenBits(actualTarget);
+               
+               baselineMissing = true;
+               writePNG(actualTarget);
+               // writePNG() creates error handlers which will handle the fail 
and stepComplete().
+       }
+
+       public function readPNG():void
+       {
+               var req:URLRequest = new URLRequest();
+               if (UnitTester.isApollo) 
+               {
+                       req.url = encodeURI2(CompareBitmap.adjustPath (url));
+               } 
+               else
+        {
+            req.url = url;
+            var base:String = normalizeURL(context.application.url);
+            base = base.substring(0, base.lastIndexOf("/"));
+            while (req.url.indexOf("../") == 0)
+            {
+                    base = base.substring(0, base.lastIndexOf("/"));
+                    req.url = req.url.substring(3);
+            }
+
+            req.url = encodeURI2(base + "/" + req.url);
+        }
+               //      req.url = encodeURI2(url);
+               // }
+       
+               reader = new Loader();
+
+               trace ("readPNG:requesting url: " + req.url);
+       reader.contentLoaderInfo.addEventListener(Event.COMPLETE, 
readCompleteHandler);
+       
reader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
readErrorHandler);
+       reader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, 
readErrorHandler);
+
+               reader.load (req);      
+       }
+
+
+       public static var adjustPath:Function = function(url:String):String { 
return url; };
+
+
+
+
+    public function getPngByteArray(target:DisplayObject, 
bitmapData:BitmapData):ByteArray 
+       {
+               // add png headers
+               if (UnitTester.createBitmapReferences)
+               {
+                       var targetSize:Point = getTargetSize(target);
+                       var stagePt:Point = target.localToGlobal(new Point(0, 
0));
+            var altPt:Point = target.localToGlobal(targetSize);
+            stagePt.x = Math.min(stagePt.x, altPt.x);
+            stagePt.y = Math.min(stagePt.y, altPt.y);
+                       bitmapData = new BitmapData(targetSize.x, targetSize.y);
+                       bitmapData.draw(target.stage, new Matrix(1, 0, 0, 1, 
-stagePt.x, -stagePt.y));
+
+               } 
+               var png:MustellaPNGEncoder = new MustellaPNGEncoder();
+               var ba:ByteArray = png.encode (bitmapData);
+
+               return ba;
+       }
+
+       public function writeBaselines(target:DisplayObject, 
writeDisplayList:Boolean = true):void 
+       {
+               var req:URLRequest = new URLRequest();
+               writer = new URLLoader();
+               req.method = "POST";
+               
+               /**
+                * either we got called here to write new baselines
+                * or to save a .bad.png for investigation
+                * in addition, with failures, we upload baseline and failure 
to a server
+                */
+               if (UnitTester.createBitmapReferences) 
+               {       
+                       fileSuffix = "";
+               } 
+               
+
+               if (writeDisplayList)
+               {
+                       var s:String = getDisplayListXML(target).toXMLString();
+                       // request data goes on the URL Request
+                       req.data = s;
+                       
+                       req.contentType = "text/xml";
+                       if (UnitTester.isApollo) 
+                       { 
+                               req.url = 
encodeURI2(UnitTester.bitmapServerPrefix + adjustWriteURI(adjustPath(url))) + 
fileSuffix + ".xml";
+                       } else 
+                       {
+                               req.url = 
encodeURI2(UnitTester.bitmapServerPrefix + absolutePath(url)) + fileSuffix + 
".xml";
+                       }
+                       trace ("writing url: " + req.url);
+                       writer.addEventListener(Event.COMPLETE, 
writeXMLCompleteHandler);
+                       
writer.addEventListener(SecurityErrorEvent.SECURITY_ERROR, writeErrorHandler);
+                       writer.addEventListener(IOErrorEvent.IO_ERROR, 
writeErrorHandler);
+                       
+                       writer.load (req);      
+               }
+       }
+               
+       private function writeXMLCompleteHandler(event:Event):void
+       {
+               var actualTarget:DisplayObject = 
DisplayObject(context.stringToObject(target));
+               writePNG(actualTarget);
+       }
+       
+       private function writePNG(target:DisplayObject):void
+       {
+               var req:URLRequest = new URLRequest();
+               writer = new URLLoader();
+               req.method = "POST";
+               
+               var ba:ByteArray = getPngByteArray(target, screenBits);         
        
+               trace ("image size: " + ba.length);
+               // request data goes on the URL Request
+               req.data = ba;
+               // can't send this, don't need to anyway var rhArray:Array = 
new Array(new URLRequestHeader("Content-Length", new String(ba.length) ));
+               
+               req.contentType = "image/png";
+               
+               if (UnitTester.isApollo) 
+               { 
+                       req.url = encodeURI2(UnitTester.bitmapServerPrefix + 
adjustWriteURI(adjustPath(url))) + fileSuffix;
+               } else 
+               {
+                       req.url = encodeURI2(UnitTester.bitmapServerPrefix + 
absolutePath(url)) + fileSuffix;
+               }
+               trace ("writing url: " + req.url);
+               writer.addEventListener(Event.COMPLETE, writeCompleteHandler);
+               writer.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
writeErrorHandler);
+               writer.addEventListener(IOErrorEvent.IO_ERROR, 
writeErrorHandler);
+                       
+               writer.load (req);      
+                       
+
+               /// If this is about creating bitmaps, skip the upload, we're 
done
+               if (UnitTester.createBitmapReferences || UnitTester.run_id == 
"-1" || baselineMissing)
+                       return;
+
+               //// Upload
+               var writer2:URLLoader = new URLLoader();
+               var reqScreen:URLRequest = new URLRequest();
+
+               reqScreen.method = "POST";
+
+               /// we already have the screen data in hand:
+               reqScreen.data = ba;
+
+               /// fill in the blanks
+               reqScreen.contentType = "image/png";
+               reqScreen.url = UnitTester.urlAssemble ("screen", 
+                       context.testDir, context.scriptName, 
this.testResult.testID, UnitTester.run_id);
+
+               trace ("upload: " + reqScreen.url);
+               writer2.addEventListener(Event.COMPLETE, uploadCompleteHandler);
+               writer2.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
uploadErrorHandler);
+               writer2.addEventListener(IOErrorEvent.IO_ERROR, 
uploadErrorHandler);
+               writer2.load (reqScreen);
+
+
+               /// get the baseline stuff:
+               var writer3:URLLoader = new URLLoader();
+               var reqBaseline:URLRequest = new URLRequest();
+               /// needed?
+               var baBase:ByteArray = getPngByteArray(target, baselineBits);
+               
+               reqBaseline.data = baBase;
+               reqBaseline.contentType = "image/png";
+               reqBaseline.method = "POST";
+               
+               reqBaseline.url = UnitTester.urlAssemble ("baseline", 
+                       context.testDir, context.scriptName, 
this.testResult.testID, UnitTester.run_id);
+
+               trace ("upload: " + reqBaseline.url);
+               writer3.addEventListener(Event.COMPLETE, 
upload2CompleteHandler);
+               writer3.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
upload2ErrorHandler);
+               writer3.addEventListener(IOErrorEvent.IO_ERROR, 
upload2ErrorHandler);
+               writer3.load (reqBaseline);
+
+
+    }
+
+       private function adjustWriteURI(url:String):String
+       {
+               var pos:int = url.indexOf("file:///");
+               if (pos != 0)
+               {
+                       return url;
+               }
+               url = url.substring(8);
+               pos = url.indexOf("|");
+
+               if (pos != 1)
+               {
+                       return url;
+               }
+
+               var drive:String = url.substring(0, 1);
+               drive = drive.toLowerCase();
+               return drive + ":" + url.substring(2);
+       }
+
+       private var screenDone:Boolean = false;
+       private var baselineDone:Boolean = false;
+
+       private function writeCompleteHandler(event:Event):void
+       {
+               trace("baseline write successful " + event);
+               if( baselineMissing ){
+                       baselineMissing = false;
+                       testResult.doFail( baselineMissingMessage );
+               }
+               stepComplete();
+       }
+
+       private function uploadCompleteHandler(event:Event):void
+       {
+               trace("screen image upload successful " + event);
+               screenDone = true;
+               checkForStepComplete();
+       }
+
+       private function upload2CompleteHandler(event:Event):void
+       {
+               trace("baseline image upload successful " + event);
+               baselineDone = true;
+               checkForStepComplete();
+       }
+
+       private function writeErrorHandler(event:Event):void
+       {
+               if( baselineMissing ){
+                       baselineMissing = false;
+                       testResult.doFail( baselineMissingMessageFail );
+                       stepComplete();
+               }else{
+                       testResult.doFail ("error on baseline write: " + event);
+                       trace("Image baseline write failed " + event);
+                       if (UnitTester.createBitmapReferences)
+                               stepComplete();
+               }
+       }
+       private function uploadErrorHandler(event:Event):void
+       {
+               testResult.doFail ("error on baseline write: " + event);
+               trace("Image screen upload failed " + event);
+               screenDone = true;
+               checkForStepComplete();
+       }
+
+       private function upload2ErrorHandler(event:Event):void
+       {
+               testResult.doFail ("error on baseline write: " + event);
+               trace("Image baseline upload failed " + event);
+               baselineDone = true;
+               checkForStepComplete();
+       }
+
+       private function checkForStepComplete():void
+       {
+
+               if (baselineDone && screenDone)
+                       preStepComplete();
+
+
+       }
+
+       /**
+        *  customize string representation
+        */
+       override public function toString():String
+       {
+               var s:String = (UnitTester.createBitmapReferences) ? 
"CreateBitmap: " : "CompareBitmap";
+               if (target)
+                       s += ": target = " + target;
+               if (url)
+                       s += ", url = " + url;
+               return s;
+       }
+
+       private function absolutePathResult(url:String):String
+       { 
+
+                var base:String = null;
+
+               if (UnitTester.isApollo) 
+               {
+                       base = adjustWriteURI(adjustPath (url));
+               } else 
+               {
+                       base = context.application.url;
+
+               }
+
+                base = normalizeURL(base);
+               base = base.substring (base.indexOf ("mustella/tests")+14);
+
+
+               if (!UnitTester.isApollo) 
+               {
+                       base = base.substring(0, base.lastIndexOf("/"));
+               
+                       var tmp:String = url;
+
+                       while (tmp.indexOf("../") == 0)
+                       {
+                               base = base.substring(0, base.lastIndexOf("/"));
+                               tmp = tmp.substring(3);
+                       }
+
+                       return base +"/" + tmp;
+               } else
+               {
+                       return base;
+
+               }
+
+
+
+       }
+
+       private function absolutePathHttp(url:String):String
+       {
+
+               if (url.indexOf ("..") == 0)
+                       return url.substring (3);
+               else
+                       return url;
+
+
+       }
+
+
+       
+       private function absolutePath(url:String):String
+       {
+               var swf:String = normalizeURL(root.loaderInfo.url);
+
+               var pos:int = swf.indexOf("file:///");
+
+
+               if (pos != 0)
+               {
+               
+                       var posH:int = swf.indexOf("http://";);
+                       if (posH == 0)
+                       {
+                               return absolutePathHttp (url);
+                       } else
+                       {
+
+                               trace("WARNING: unexpected swf url format, no 
file:/// at offset 0");
+                               return url;
+                       }
+               }
+               swf = swf.substring(8);
+               pos = swf.indexOf("|");
+               if (pos != 1)
+               {
+                       trace("WARNING: unexpected swf url format, no | at 
offset 1 in: " + swf);
+                       // assume we're on a mac or other unix box, it will do 
no harm
+                       return "/" + swf.substring(0, swf.lastIndexOf ("/")+1)  
+ url;
+               }
+
+               var drive:String = swf.substring(0, 1);
+               drive = drive.toLowerCase();
+               return drive + ":" + swf.substring(2, swf.lastIndexOf("/") + 1) 
+ url;
+       }
+
+
+        public static function normalizeURL(url:String):String
+        {
+               var results:Array = url.split("/[[DYNAMIC]]/");
+               return results[0];
+        }
+
+
+       public function keepGoing():void
+       {
+               trace("keepgoing", url, hasEventListener("stepComplete"));
+               preStepComplete();
+       }
+
+       private function encodeURI2(s:String):String
+       {
+               var pos:int = s.lastIndexOf("/");
+               if (pos != -1)
+               {
+                       var fragment:String = s.substring(pos + 1);
+                       s = s.substring(0, pos + 1);
+                       fragment= encodeURIComponent(fragment);
+                       s = s + fragment;
+               }
+               return s;
+       }
+
+       private function compareWithVariances(bm:BitmapData):Object
+       {
+
+               var totalAllowed:int = numColorVariances * 
UnitTester.pixelToleranceMultiplier;
+               var allowed:int = totalAllowed;
+               var n:int = bm.height;
+               var m:int = bm.width;
+
+               for (var i:int = 0; i < n; i++)
+               {
+                       for (var j:int = 0; j < m; j++)
+                       {
+                               var pix:int = bm.getPixel(j, i);
+                               if (pix)
+                               {
+                                       if(!ignoreMaxColorVariance)
+                                       {
+                                               var red:int = pix >> 16 & 0xff;
+                                               var green:int = pix >> 8 & 0xff;
+                                               var blue:int = pix & 0xff;
+                                               if (red & 0x80)
+                                                       red = 256 - red;
+                                               if (blue & 0x80)
+                                                       blue = 256 - blue;
+                                               if (green & 0x80)
+                                                       green = 256 - green;
+                                               if (red > maxColorVariance ||
+                                                       blue > maxColorVariance 
||
+                                                       green > 
maxColorVariance)
+                                               {
+                                                       var max:int = 
Math.max(Math.max(red, blue), green);
+                                                       trace("CompareBitmap: 
exceeded maxColorVariance=" + maxColorVariance + " max(red,green,blue)=" + max);
+                                                       return bm;
+                                               }
+                                       }
+                                       allowed--;
+                                       if (allowed < 0)
+                                       {
+                                               trace("CompareBitmap: exceeded 
numColorVariances=" + numColorVariances);
+                                               return bm;
+                                       }
+                               }
+                       }
+               }
+               
+               trace("CompareBitmap: numColorVariances seen=" + 
String(totalAllowed - allowed));
+               return 0;
+       }
+
+       private function checkEmbeddedFonts(target:Object):Boolean
+       {
+               if ("rawChildren" in target)
+                       target = target.rawChildren;
+
+               if (target is TextField)
+               {
+                       if (target.embedFonts == false)
+                               return false;
+                       if (target.antiAliasType == "advanced")
+                               return false;
+                       return true;
+               }
+               else if ("numChildren" in target)
+               {
+                       var n:int = target.numChildren;
+                       for (var i:int = 0; i < n; i++)
+                       {
+                               if (!checkEmbeddedFonts(target.getChildAt(i)))
+                                       return false;
+                       }
+               }
+               
+               return true;
+       }
+       
+       protected function preStepComplete():void
+       {
+               if (baselineBits != null)
+            baselineBits.dispose();
+        if (screenBits != null)
+            screenBits.dispose();
+
+               reader=null;
+               writer=null;
+               
+               stepComplete();
+       }
+
+       /* this was sometimes getting called before the image was loaded into
+          'reader' which made it null and then the readCompleteHandler failed.
+       override protected function stepComplete():void 
+       { 
+
+                if (baselineBits != null)
+                        baselineBits.dispose();
+                if (screenBits != null)
+                        screenBits.dispose();
+
+               reader=null;
+               writer=null;
+               
+               super.stepComplete();
+
+
+       }*/
+
+       /****** DisplayList Comparision ******/
+       protected function getDisplayListProperties(d:DisplayObject, 
noMask:Boolean = false):XML
+       {
+               var xml:XML;
+               var n:int;
+               var i:int;
+               var childXML:XML;
+               var s:String = getQualifiedClassName(d);
+               s = s.replace("::", ".");
+               xml = new XML("<" + s + "/>");
+               s = d.transform.concatenatedColorTransform.toString();
+               if (s != identityColorTransform)
+                       xml.@concatenatedColorTransform = s;
+               if (d.transform.matrix)
+               {
+                       s = d.transform.matrix.toString();
+                       if (s != identityMatrix)
+                       {
+                               if (s.indexOf("(a=1, b=0, c=0, d=1, ") == -1)
+                                       xml.@matrix = s;
+                       }
+               }
+               else
+               {
+                       s = d.transform.matrix3D.rawData.toString();
+                       xml.@matrix3D = s;
+               }
+               if (d.x != 0)
+                       xml.@x = d.x;
+               if (d.y != 0)
+                       xml.@y = d.y;
+               xml.@width = d.width;
+               xml.@height = d.height;
+               if (xml.visible == false)
+                       xml.@visible = "false";
+               if (d.mask && d.mask != d.parent && !noMask)
+               {
+                       xml.mask = <mask/>;
+                       childXML = getDisplayListProperties(d.mask, true);
+                       xml.mask.appendChild = childXML;
+               }
+               if (d.scrollRect)
+               {
+                       s = d.scrollRect.toString();
+                       xml.@scrollRect = s;
+               }
+               if (d.blendMode && d.blendMode != "normal")
+                       xml.@blendMode = d.blendMode;
+               if (d.cacheAsBitmap)
+                       xml.@cacheAsBitmap = "true";
+        try {
+               if (d.filters && d.filters.length > 0)
+               {
+                       s = d.filters.toString();
+                       xml.@filters = s;
+               }
+        } catch (e:Error)
+        {
+            // seems to throw arg error when Shader applied
+        }
+               if (d.opaqueBackground)
+                       xml.@opaqueBackground = "true";
+               if (d.scale9Grid)
+               {
+                       s = d.scale9Grid.toString();
+                       xml.@scale9Grid = s;
+               }
+               if (d is TextField)
+               {
+                       xml.@underline = 
TextField(d).defaultTextFormat.underline;
+                       xml.htmlText = TextField(d).htmlText;
+               }
+               if (d is Loader && 
Loader(d).contentLoaderInfo.contentType.indexOf("image") != -1)
+               {
+                       s = Loader(d).contentLoaderInfo.url;
+                       s = s.substring(s.lastIndexOf("/") + 1);
+                       xml.@loaderbitmap = s;
+               }
+               if (d is TextLine)
+               {
+                       var tl:TextLine = TextLine(d);
+                       xml.@ascent = tl.ascent;
+                       xml.@descent = tl.descent;
+                       xml.@atomCount = tl.atomCount;
+                       xml.@hasGraphicElement = tl.hasGraphicElement;
+                       if (tl.textBlock)
+                       {
+                               var tb:TextBlock = TextLine(d).textBlock;
+                               var ce:ContentElement = tb.content;
+                               s = ce.rawText.substr(tl.textBlockBeginIndex, 
tl.rawTextLength);
+                               xml.@text = s;
+                       }
+               }
+               
+               if (d is IRawChildrenContainer)
+               {
+                       var rawChildren:IChildList = 
IRawChildrenContainer(d).rawChildren;
+                       n = rawChildren.numChildren;
+                       for (i = 0; i < n; i++)
+                       {
+                               childXML = 
getDisplayListProperties(rawChildren.getChildAt(i));
+                               xml.appendChild(childXML);                      
        
+                       }
+               }
+               else if (d is DisplayObjectContainer)
+               {
+                       var doc:DisplayObjectContainer = d as 
DisplayObjectContainer;
+                       n = doc.numChildren;
+                       for (i = 0; i < n; i++)
+                       {
+                var child:DisplayObject = doc.getChildAt(i);
+                if (child) // was null in an FCK test.
+                {
+                               childXML = getDisplayListProperties(child);
+                               xml.appendChild(childXML);                      
        
+                }
+                else
+                    xml.appendChild(<NullChild />);
+                       }
+               }
+               return xml;
+       }
+       
+       // scan entire display list, but only dump objects intersecting target
+       protected function getDisplayListXML(target:DisplayObject):XML
+       {
+               var i:int;
+               var n:int;
+               var child:DisplayObject;
+               var childXML:XML;
+               
+               var doc:DisplayObjectContainer = 
DisplayObjectContainer(target.root);
+               var xml:XML = <DisplayList />;
+               if (doc is IRawChildrenContainer)
+               {
+                       var rawChildren:IChildList = 
IRawChildrenContainer(doc).rawChildren;
+                       n = rawChildren.numChildren;
+                       for (i = 0; i < n; i++)
+                       {
+                               child = rawChildren.getChildAt(i);
+                               if (target.hitTestObject(child))
+                               {
+                                       childXML = 
getDisplayListProperties(child);
+                                       xml.appendChild(childXML);      
+                               }
+                       }
+               }
+               else 
+               {
+                       n = doc.numChildren;
+                       for (i = 0; i < n; i++)
+                       {
+                               child = doc.getChildAt(i);
+                               if (target.hitTestObject(child))
+                               {
+                                       childXML = 
getDisplayListProperties(child);
+                                       xml.appendChild(childXML);              
                                                        
+                               }
+                       }
+               }
+               return xml;
+       }
+
+       private function differ(s:String, t:String):Boolean
+       {
+               var retval:Boolean = false;
+               
+               var sl:Array = s.split("\n");
+               var tl:Array = t.split("\n");
+               trace(sl.length, tl.length);
+               var n:int = Math.max(sl.length, tl.length);
+               for (var i:int = 0; i < n; i++)
+               {
+                       var a:String = (i < sl.length) ? sl[i] : "";
+                       var b:String = (i < tl.length) ? tl[i] : "";
+                       if (a != b)
+                       {
+                               a = trimTag(a);
+                               b = trimTag(b);
+                               if (a != b && !nullChildOrStaticText(a, b))
+                               {
+                                       retval = true;
+                                       var c:String = "";
+                                       var d:String = "";
+                                       trace(i, "cur: ", a);
+                                       trace(i, "xml: ", b);
+                                       var m:int = Math.max(a.length, 
b.length);
+                                       for (var j:int = 0; j < m; j++)
+                                       {
+                                               c += a.charCodeAt(j) + " ";
+                                               d += b.charCodeAt(j) + " ";
+                                       }
+                                       trace(i, "cur: ", c);
+                                       trace(i, "xml: ", d);
+                               }
+                       }
+               }
+               return retval;
+       }
+       
+       // attempt to strip off random unique name chars for embedded assets
+       private function trimTag(a:String):String
+       {
+               var c:int;
+               var d:int;
+               
+               d = a.indexOf("<");
+               if (d != -1)
+               {
+                       c = a.indexOf(" ", d);
+                       if (c == -1 && a.length > d + 2 && a.charAt(d + 1) == 
'/')
+                               c = a.indexOf(">"); // closing tag
+                       if (c != -1)
+                       {
+                               var rest:String = a.substring(c);
+                               for (var i:int = c - 1;i > 0; i--)
+                               {
+                                       var ch:String = a.charAt(i);
+                                       if ((ch >= '0' && ch <= '9') || ch == 
'_')
+                                       {
+                                               // assume it is a random char
+                                       }
+                                       else
+                                               break;
+                               }
+                               return a.substring(0, i + 1) + rest;
+                       }
+               }
+               return a;
+       }
+       
+    // attempt to strip off random unique name chars for embedded assets
+    private function trimName(a:String):String
+    {
+        var c:int;
+        var d:int;
+        
+        c = a.length;
+        for (var i:int = c - 1;i >= 0; i--)
+        {
+            var ch:String = a.charAt(i);
+            if ((ch >= '0' && ch <= '9') || ch == '_')
+            {
+                // assume it is a random char
+            }
+            else
+                break;
+        }
+        return a.substring(0, i + 1);
+    }
+
+    // static text seems to float around a bit so ignore it.
+       private function nullChildOrStaticText(a:String, b:String):Boolean
+       {
+               if (a.indexOf("<NullChild") != -1)
+                       return true;
+               if (b.indexOf("<NullChild") != -1)
+                       return true;
+               if (a.indexOf("<flash.text.StaticText") != -1)
+                       return true;
+               if (b.indexOf("<flash.text.StaticText") != -1)
+                       return true;
+               return false;
+       }
+
+    private function xmldiffer(s:String, t:String):Boolean
+    {
+        var retval:Boolean = false;
+        
+        var xmls:XML = XML(s);
+        var xmlt:XML = XML(t);
+        retval = compareNodes(xmls, xmlt);
+        if (retval)
+            differ(s, t);
+        return retval;
+    }
+    
+    private static var xywidthheight:Object = { x: 1, y: 1, width: 1, height: 
1};
+    
+    private function compareNodes(s:XML, t:XML):Boolean
+    {
+        var retval:Boolean = false;
+        var q:String;
+        var i:int;
+        var j:int;
+        var n:int;
+        var m:int;
+        var st:String;
+        var tt:String;
+        var sv:String;
+        var tv:String;
+        
+        if (s.toXMLString() == t.toXMLString())
+            return false;
+        
+        // compare tag names
+        var sn:String = s.name().toString();
+        var tn:String = t.name().toString();
+        var sparts:Array = sn.split(".");
+        var tparts:Array = tn.split(".");
+        n = sparts.length;
+        for (i = 0; i < n; i++)
+            sparts[i] = trimName(sparts[i]);
+        n = tparts.length;
+        for (i = 0; i < n; i++)
+            tparts[i] = trimName(tparts[i]);
+        sn = sparts.join(".");
+        tn = tparts.join(".");
+        if (tn != sn)
+        {
+            if (sn == "NullChild" || sn == "flash.display.StaticText" ||
+                tn == "NullChild" || tn == "flash.display.StaticText")
+            {
+                // inconsistent behavior around StaticText   
+                return false;
+            }
+            else if (!oneMoreNameCompare(sn, tn))
+            {
+                trace("tag name mismatch: cur=", sn, "xml=", tn);
+                retval = true;
+            }
+        }
+        
+        var sa:XMLList = s.attributes();
+        var ta:XMLList = t.attributes();
+        n = sa.length();
+        m = ta.length();
+        if (n != m)
+        {
+            trace(sn, "different number of attributes: cur=", n, "xml=", m);
+            retval = true;
+        }
+        else
+        {
+            for (i = 0; i < n; i++)
+            {
+                st = sa[i].name().toString();
+                tt = ta[i].name().toString();
+                if (st != tt)
+                {
+                    trace(sn, "attribute name mismatch: cur=", st, "xml=", tt);
+                    retval = true;
+                }
+                else 
+                {
+                    sv = s['@' + st].toString();
+                    tv = t['@' + tt].toString();
+                    if (sv != tv)
+                    {
+                        if (xywidthheight[st] == 1)
+                        {
+                            var sf:Number = Number(sv);
+                            var tf:Number = Number(tv);
+                            if (Math.abs(tf - sf) > maxMatrixVariance)
+                            {
+                                trace(sn + '@' + st, "attribute value 
mismatch: cur=", sv, "xml=", tv);
+                                retval = true;
+                            }
+                        }
+                        else if (st == "matrix")
+                        {
+                            // strip parens
+                            sv = sv.substring(1, sv.length - 2);
+                            tv = tv.substring(1, tv.length - 2);
+                            sparts = sv.split(",");
+                            tparts = tv.split(",");
+                            m = sparts.length;
+                            for (j = 0; j < m; j++)
+                            {
+                                sv = sparts[j];
+                                tv = tparts[j];
+                                sv = sv.split("=")[1];
+                                tv = tv.split("=")[1];
+                                sf = Number(sv);
+                                tf = Number(tv);
+                                if (Math.abs(tf - sf) > maxMatrixVariance)
+                                {
+                                    trace(sn + '@' + st, "matrix value 
mismatch: cur=", sv, "xml=", tv);
+                                    retval = true;                             
       
+                                }
+                            }
+                        }
+                        else
+                        {
+                            trace(sn + '@' + st, "attribute value mismatch: 
cur=", sv, "xml=", tv);
+                            retval = true;
+                        }
+                    }
+                }
+            }
+        }
+        
+        var sl:XMLList = s.children();
+        var tl:XMLList = t.children();
+        n = sl.length();
+        m = tl.length();
+        if (n != m)
+        {
+            trace(sn, "different number of children: cur=", n, "xml=", m);
+            retval = true;
+        }
+        else
+        {
+            for (i = 0; i < n; i++)
+            {
+                var nk:String = sl[i].nodeKind();
+                if (nk == "text")
+                {
+                    if (sl[i].text() != tl[i].text())
+                    {
+                        trace(sn, "different number of text nodes: cur=", 
sl[i].text(), "xml=", tl[i].text());
+                        retval = true;
+                    }
+                }
+                else if (nk == "element")
+                {
+                    if (compareNodes(sl[i], tl[i]))
+                        retval = true;
+                }
+            }
+        }
+        return retval;
+    }
+
+       private function oneMoreNameCompare(a:String, b:String):Boolean
+       {
+               var aParts:Array = a.split("_");
+               var bParts:Array = b.split("_");
+               var i:int;
+               var n:int;
+               n = aParts.length;
+               for (i = 0; i < n; i++)
+                       aParts[i] = trimName(aParts[i]);
+               n = bParts.length;
+               for (i = 0; i < n; i++)
+                       bParts[i] = trimName(bParts[i]);
+               a = aParts.join("_");
+               b = bParts.join("_");
+               return a == b;
+       }
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ConditionalValue.as
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/ConditionalValue.as 
b/mustella/src/main/flex/ConditionalValue.as
new file mode 100644
index 0000000..b5edc4d
--- /dev/null
+++ b/mustella/src/main/flex/ConditionalValue.as
@@ -0,0 +1,356 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT 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
+{
+COMPILE::SWF
+{
+       import flash.events.*;
+       import mx.utils.*;
+}
+COMPILE::JS
+{
+    import org.apache.flex.events.EventDispatcher;
+}
+
+       [Event(name="valueExpression", type="RunCodeEvent")]    
+       public class ConditionalValue extends EventDispatcher
+       {
+               // Asserts such as AssertPropertyValue use value=...
+               public var value:Object = null;
+               
+               // CompareBitmap uses url=...
+               public var url:String = null;
+               
+               
+               /**
+               * These are possibilities for the environment.
+               * Use Inspectable so that test authoring is a little easier.
+               * For details: 
https://zerowing.corp.adobe.com/display/flexmobile/Multiple+Device%2C+DPI%2C+OS+Support
+               **/
+               
+               [Inspectable(enumeration="win,mac,android,iphone,ios,qnx")]
+               public var os:String = null;
+
+               
[Inspectable(enumeration="android22,android23,android234,android31,iphone421,iphone50,ios4,ios5,ios6")]
+               public var osVersion:String = null;
+               
+               /**
+                * The targetOS is either null or set in the UnitTester's cv as 
the value to match
+                * against the os properties from <ConditionalValue> elements 
present in the test
+                * cases. See MultiResult.chooseCV()
+                */
+               [Inspectable(enumeration="android,ios")]
+               public var targetOS:String = null;
+
+               // General, "marketing number" pixel density
+               [Inspectable(enumeration="120,160,240,320,480,640")]
+               public var deviceDensity:Number = -1;
+
+               // Exact pixel density reported by AIR's Capabilities.screenDPI
+               public var screenDPI:Number = -1;
+
+               // Exact
+               public var deviceWidth:Number = -1;
+
+               // Exact
+               public var deviceHeight:Number = -1;
+
+               [Inspectable(enumeration="16,32")]
+               public var color:Number = -1;
+
+               
[Inspectable(enumeration="air,desire,droid,droid2,droidPro,droidX,evo,incredible,iPad,iPad2,iPodTouch3GS,iPodTouch4G,nexusOne,playbook,xoom")]
+               public var device:String = null;
+
+               /**
+               * These are used to make file name legible to humans and allow
+               * parsing of them.
+               **/
+               public static const SCREENDPI_SUFFIX:String = "scrDPI";
+               public static const DENSITY_SUFFIX:String = "ppi";
+               public static const WIDTH_SUFFIX:String = "w";
+               public static const HEIGHT_SUFFIX:String = "h";
+               public static const COLOR_SUFFIX:String = "bit";
+               public static const PNG_SUFFIX:String = ".png";
+               public static const DELIMITER1:String = "@"; // between testID 
and settings
+               public static const DELIMITER2:String = "_"; // between settings
+               
+               /**
+               * Constructor
+               **/
+               public function ConditionalValue(){}
+
+               /**
+               * Returns true if all items are at default values (e.g. the 
default, catch-all CV).
+               **/
+               public function isDefault():Boolean{
+                       return ((os == null) &&
+                                       (osVersion == null) &&
+                                       (screenDPI == -1) &&
+                                       (deviceDensity == -1) &&
+                                       (deviceWidth == -1) &&
+                                       (deviceHeight == -1) &&
+                                       (color == -1) &&
+                                       (device == null) &&
+                                       (targetOS == null)
+                               );
+               }
+
+               /**
+               * Uses the properties which are set to create a file name for a 
baseline image.
+               **/
+               public function createFilename(testID:String):String{
+                       var ret:String = null;
+                       var consistent:Boolean = false;
+                       var testCV:ConditionalValue = new ConditionalValue();
+                       
+                       ret = testID + DELIMITER1;
+
+                       if( os != null ) {
+                               ret += os + DELIMITER2;
+                       }
+                       
+/*                     if( targetOS != null ) {
+                               ret += targetOS + DELIMITER2;
+                       }*/
+
+                       if( osVersion != null ){
+                               ret += osVersion + DELIMITER2;
+                       }
+
+                       if( screenDPI > -1 ){
+                               ret += screenDPI.toString() + SCREENDPI_SUFFIX 
+ DELIMITER2;
+                       }
+
+                       if( deviceDensity > -1 ){
+                               ret += deviceDensity.toString() + 
DENSITY_SUFFIX + DELIMITER2;
+                       }
+                       
+                       if( deviceWidth > -1 ){
+                               ret += deviceWidth.toString() + WIDTH_SUFFIX + 
DELIMITER2;
+                       }
+                       
+                       if( deviceHeight > -1 ){
+                               ret += deviceHeight.toString() + HEIGHT_SUFFIX 
+ DELIMITER2;
+                       }
+                       
+                       if( color > -1 ){
+                               ret += color.toString() + COLOR_SUFFIX + 
DELIMITER2;
+                       }
+                       
+                       if( device != null ){
+                               ret += device;
+                       }else{
+                               // Remove last DELIMITER2.
+                               if( ret.lastIndexOf(DELIMITER2) == ret.length - 
1 ){
+                                       ret = ret.substr(0, ret.length - 1);
+                               }
+                       }
+                       
+                       ret += PNG_SUFFIX;
+                       
+                       trace("ConditionalValue ret="+ret+"; 
screenDPI="+screenDPI+"; density="+deviceDensity);
+                       
+                       // Be sure we'll be able to parse what we wrote when we 
read it later.
+                       if( testCV.parseFilename( ret ) ){
+                               consistent = (testCV.os == os &&
+                                                        testCV.osVersion == 
osVersion &&
+                                                        testCV.screenDPI == 
screenDPI &&
+                                                        testCV.deviceDensity 
== deviceDensity &&
+                                                        testCV.deviceWidth == 
deviceWidth &&
+                                                        testCV.deviceHeight == 
deviceHeight &&
+                                                        testCV.color == color 
&&
+                                                        testCV.device == 
device );
+                       }
+                       
+                       if( consistent ){
+                               return ret;
+                       }else{
+                               trace("ConditionalValue inconsistency:");
+                               trace("\twhat\ttestCV\tactualCV");
+                               trace("\tos\t" + testCV.os + "\t" + os);
+                               trace("\tosVersion\t" + testCV.osVersion + "\t" 
+ osVersion);
+                               trace("\tscreenDPI\t" + testCV.screenDPI + "\t" 
+ screenDPI);
+                               trace("\tdeviceDensity\t" + 
testCV.deviceDensity + "\t" + deviceDensity);
+                               trace("\tdeviceWidth\t" + testCV.deviceWidth + 
"\t" + deviceWidth);
+                               trace("\tdeviceHeight\t" + testCV.deviceHeight 
+ "\t" + deviceHeight);
+                               trace("\tcolor\t" + testCV.color + "\t" + 
color);
+                               trace("\tdevice\t" + testCV.device + "\t" + 
device);
+                               
+                               return null;
+                       }
+               }
+               
+               /** 
+               * Populate values from a filename.
+               **/
+               public function parseFilename(filename:String):Boolean{
+            COMPILE::SWF
+            {
+                       var tokens:Array = null;
+                       var curToken:String = null;
+                       var tokenDone:Boolean = false;
+                       var i:int = 0;
+                       var j:int = 0;
+                       
+                       
+                       if( filename != null ){
+                               // Remove the extension.
+                               if( filename.indexOf( PNG_SUFFIX ) > -1 ){
+                                       filename = filename.substring( 0, 
filename.indexOf( PNG_SUFFIX ) );
+                               }
+                               
+                               if( (filename != null) && (StringUtil.trim( 
filename ) != "") ){
+                                       tokens = filename.split( DELIMITER1 );
+                               }
+                               
+                               // tokens[0] is the test case, and tokens[1] is 
the data.
+                               tokens = tokens[1].split( DELIMITER2 );
+
+                               if( (tokens != null) && (tokens.length > 0) ){
+                                       for( i = 0; i < tokens.length; ++i ){
+                                               curToken = tokens[ i ];
+                                               tokenDone = false;
+                                               
+                                               // Look for os.
+                                               for( j = 0; j < 
DeviceNames.OS_VALUES.length; ++j ){
+                                                       if( curToken == 
DeviceNames.OS_VALUES[ j ] ){
+                                                               os = curToken;
+                                                               targetOS = 
curToken;
+                                                               tokenDone = 
true;
+                                                               break;
+                                                       }
+                                               }
+                                               
+                                               if( !tokenDone ){
+                                                       // Look for os version.
+                                                       for( j = 0; j < 
DeviceNames.OS_VERSION_VALUES.length; ++j ){
+                                                               if( curToken == 
DeviceNames.OS_VERSION_VALUES[ j ] ){
+                                                                       
osVersion = curToken;
+                                                                       
tokenDone = true;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for screenDPI
+                                                       if( curToken.indexOf( 
SCREENDPI_SUFFIX ) > -1 ){
+                                                               curToken = 
curToken.substring( 0, curToken.indexOf( SCREENDPI_SUFFIX ) );
+                                                               if( (curToken 
!= null) && (StringUtil.trim( curToken ) != "") ){
+                                                                       
screenDPI = new Number( curToken );
+                                                                       
tokenDone = true;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for density.
+                                                       if( curToken.indexOf( 
DENSITY_SUFFIX ) > -1 ){
+                                                               curToken = 
curToken.substring( 0, curToken.indexOf( DENSITY_SUFFIX ) );
+                                                               if( (curToken 
!= null) && (StringUtil.trim( curToken ) != "") ){
+                                                                       
deviceDensity = new Number( curToken );
+                                                                       
tokenDone = true;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for width.
+                                                       if( curToken.indexOf( 
WIDTH_SUFFIX ) > -1 ){
+                                                               curToken = 
curToken.substring( 0, curToken.indexOf( WIDTH_SUFFIX ) );
+                                                               if( (curToken 
!= null) && (StringUtil.trim( curToken ) != "") ){
+                                                                       
deviceWidth = new Number( curToken );
+                                                                       
tokenDone = true;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for height.
+                                                       if( curToken.indexOf( 
HEIGHT_SUFFIX ) > -1 ){
+                                                               curToken = 
curToken.substring( 0, curToken.indexOf( HEIGHT_SUFFIX ) );
+                                                               if( (curToken 
!= null) && (StringUtil.trim( curToken ) != "") ){
+                                                                       
deviceHeight = new Number( curToken );
+                                                                       
tokenDone = true;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for color.
+                                                       if( curToken.indexOf( 
COLOR_SUFFIX ) > -1 ){
+                                                               curToken = 
curToken.substring( 0, curToken.indexOf( COLOR_SUFFIX ) );
+                                                               if( (curToken 
!= null) && (StringUtil.trim( curToken ) != "") ){
+                                                                       color = 
new Number( curToken );
+                                                                       
tokenDone = true;
+                                                               }
+                                                       }
+                                               }
+
+                                               if( !tokenDone ){
+                                                       // Look for device.
+                                                       for( j = 0; j < 
DeviceNames.DEVICE_VALUES.length; ++j ){
+                                                               if( curToken == 
DeviceNames.DEVICE_VALUES[ j ] ){
+                                                                       device 
= curToken;
+                                                                       
tokenDone = true;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               
+                                               if( !tokenDone ){
+                                                       trace("trouble with 
token: " + curToken);
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       // If anything went wrong, tokenDone will be false.
+                       return tokenDone;
+            }
+            COMPILE::JS
+            {
+                return false;
+            }
+               }
+
+               /**
+               * Return a list of the properties.
+               **/
+        COMPILE::SWF
+               override public function toString():String{
+                       var ret:String;
+                       
+                       ret = "\tvalue=" + String(value);
+                       ret += "\n\turl=" + url;
+                       ret += "\n\tos=" + os;
+                       ret += "\n\ttargetOS=" + targetOS;
+                       ret += "\n\tosVersion=" + osVersion;
+                       ret += "\n\tscreenDPI=" + screenDPI;
+                       ret += "\n\tdeviceDensity=" + deviceDensity;
+                       ret += "\n\tdeviceWidth=" + deviceWidth;
+                       ret += "\n\tdeviceHeight=" + deviceHeight;
+                       ret += "\n\tcolor=" + color;
+                       ret += "\n\tdevice=" + device;
+                       
+                       return ret;
+               }
+       
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.ICO
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.ICO
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.ICO
new file mode 100644
index 0000000..b1afed3
Binary files /dev/null and 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.ICO
 differ

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.cpp
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.cpp
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.cpp
new file mode 100644
index 0000000..16e09a9
--- /dev/null
+++ 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.cpp
@@ -0,0 +1,362 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// ContinueAfterRuntimeException.cpp : Defines the entry point for the 
application.
+//
+
+#include "stdafx.h"
+#include "resource.h"
+
+#define MAX_LOADSTRING 100
+
+// Global Variables:
+HINSTANCE hInst;                                                               
// current instance
+TCHAR szTitle[MAX_LOADSTRING];                                                 
        // The title bar text
+TCHAR szWindowClass[MAX_LOADSTRING];                                           
                // The title bar text
+TCHAR szPlayer[] = "Adobe Flash Player 9";
+TCHAR szPlayer10[] = "Adobe Flash Player 10";
+
+UINT timer;
+
+// Foward declarations of functions included in this code module:
+ATOM                           MyRegisterClass(HINSTANCE hInstance);
+BOOL                           InitInstance(HINSTANCE, int);
+LRESULT CALLBACK       WndProc(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK       About(HWND, UINT, WPARAM, LPARAM);
+
+WSADATA wsaData;
+
+hostent* localHost;
+char* localIP;
+struct sockaddr_in sockaddr;
+SOCKADDR connaddr;
+int addrlen = sizeof(connaddr);
+
+int iResult;
+SOCKET ConnectSocket = INVALID_SOCKET;
+SOCKET ListenSocket = INVALID_SOCKET;
+
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+                     HINSTANCE hPrevInstance,
+                     LPSTR     lpCmdLine,
+                     int       nCmdShow)
+{
+       // TODO: Place code here.
+       MSG msg;
+       HACCEL hAccelTable;
+
+       // Initialize global strings
+       LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
+       LoadString(hInstance, IDC_CONTINUEAFTERRUNTIMEEXCEPTION, szWindowClass, 
MAX_LOADSTRING);
+       MyRegisterClass(hInstance);
+
+       // Initialize Winsock
+       iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+       if (iResult != 0) {
+               return 1;
+       }
+
+       // Perform application initialization:
+       if (!InitInstance (hInstance, nCmdShow)) 
+       {
+               return FALSE;
+       }
+
+       hAccelTable = LoadAccelerators(hInstance, 
(LPCTSTR)IDC_CONTINUEAFTERRUNTIMEEXCEPTION);
+
+       // Main message loop:
+       while (GetMessage(&msg, NULL, 0, 0)) 
+       {
+               if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
+               {
+                       TranslateMessage(&msg);
+                       DispatchMessage(&msg);
+               }
+       }
+
+       // shutdown the connection since no more data will be sent
+       iResult = shutdown(ListenSocket, SD_BOTH);
+       closesocket(ListenSocket);
+       ListenSocket = INVALID_SOCKET;
+
+       WSACleanup();
+       return msg.wParam;
+}
+
+
+
+//
+//  FUNCTION: MyRegisterClass()
+//
+//  PURPOSE: Registers the window class.
+//
+//  COMMENTS:
+//
+//    This function and its usage is only necessary if you want this code
+//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
+//    function that was added to Windows 95. It is important to call this 
function
+//    so that the application will get 'well formed' small icons associated
+//    with it.
+//
+ATOM MyRegisterClass(HINSTANCE hInstance)
+{
+       WNDCLASSEX wcex;
+
+       wcex.cbSize = sizeof(WNDCLASSEX); 
+
+       wcex.style                      = CS_HREDRAW | CS_VREDRAW;
+       wcex.lpfnWndProc        = (WNDPROC)WndProc;
+       wcex.cbClsExtra         = 0;
+       wcex.cbWndExtra         = 0;
+       wcex.hInstance          = hInstance;
+       wcex.hIcon                      = LoadIcon(hInstance, 
(LPCTSTR)IDI_CONTINUEAFTERRUNTIMEEXCEPTION);
+       wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
+       wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
+       wcex.lpszMenuName       = (LPCSTR)IDC_CONTINUEAFTERRUNTIMEEXCEPTION;
+       wcex.lpszClassName      = szWindowClass;
+       wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
+
+       return RegisterClassEx(&wcex);
+}
+
+//
+//   FUNCTION: InitInstance(HANDLE, int)
+//
+//   PURPOSE: Saves instance handle and creates main window
+//
+//   COMMENTS:
+//
+//        In this function, we save the instance handle in a global variable 
and
+//        create and display the main program window.
+//
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+   HWND hWnd;
+
+   hInst = hInstance; // Store instance handle in our global variable
+
+   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
+      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
+
+   if (!hWnd)
+   {
+      return FALSE;
+   }
+
+   timer = SetTimer(hWnd, 1, 1000, NULL);
+
+       localHost = gethostbyname("");
+       localIP = "127.0.0.1"; //inet_ntoa (*(struct in_addr 
*)*localHost->h_addr_list);
+
+#ifdef _DEBUG
+       OutputDebugString("Listening on socket ");
+       OutputDebugString(localIP);
+       OutputDebugString("\n");
+#endif
+
+       ShowWindow(hWnd, nCmdShow);
+    UpdateWindow(hWnd);
+
+
+       ZeroMemory( &sockaddr, sizeof(sockaddr) );
+       // Set up the sockaddr structure
+       sockaddr.sin_family = AF_INET;
+       sockaddr.sin_addr.s_addr = inet_addr(localIP);
+       sockaddr.sin_port = htons(2561);
+
+       // Create a SOCKET for connecting to server
+       ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 
+       if (ListenSocket == INVALID_SOCKET) 
+       {
+               return FALSE;
+       }
+       iResult = bind(ListenSocket, (SOCKADDR *)&sockaddr, sizeof(sockaddr));
+       if (iResult == SOCKET_ERROR) 
+       {
+               closesocket(ListenSocket);
+               ListenSocket = INVALID_SOCKET;
+               return FALSE;
+       }
+       iResult = listen(ListenSocket, 1);
+       if (iResult == SOCKET_ERROR) 
+       {
+               closesocket(ListenSocket);
+               ListenSocket = INVALID_SOCKET;
+               return FALSE;
+       }
+
+   WSAAsyncSelect(ListenSocket, hWnd, EM_SETSEL, FD_CLOSE);
+
+   return TRUE;
+}
+
+void CheckForExceptionDialog(HWND hWnd)
+{
+       hWnd = GetWindow(hWnd, GW_HWNDFIRST);
+       while (hWnd)
+       {
+               char szTitle[1024];
+               GetWindowText(hWnd, szTitle, 256);
+               if (lstrcmp(szTitle, szPlayer) == 0 || lstrcmp(szTitle, 
szPlayer10) == 0)
+               {
+                       HWND hDlg = hWnd; 
+                       HWND hChild = GetWindow(hWnd, GW_CHILD);
+                       char szError[1024];
+                       szError[0] = '\0';
+                       HWND hButton = (HWND)INVALID_HANDLE_VALUE;
+                       LONG idButton = 0;
+                       while (hChild)
+                       {
+                               GetWindowText(hChild, szTitle, 1024);
+                               if (lstrcmp(szTitle, "&Continue") == 0)
+                               {
+                                       idButton = GetWindowLong(hChild, 
GWL_ID);
+                                       hButton = hChild;
+                               }
+                               else 
+                               {
+                                       char szClassName[256];
+                                       GetClassName(hChild, szClassName, 256);
+                                       if (lstrcmp(szClassName, "Edit") == 0)
+                                       {
+                                               SendMessage(hChild, WM_GETTEXT, 
MAKELONG(LOWORD(1024), 0), (LONG)szError);
+                                       }
+                               }
+                               hChild = GetWindow(hChild, GW_HWNDNEXT);
+                       }
+                       if (hButton != INVALID_HANDLE_VALUE)
+                       {
+                               if (ConnectSocket != INVALID_SOCKET)
+                               {
+                                       // Send an initial buffer
+                                       iResult = send( ConnectSocket, szError, 
(int)strlen(szError), 0 );
+                                       if (iResult == SOCKET_ERROR) 
+                                       {
+#ifdef _DEBUG
+                                               OutputDebugString("Error 
sending to socket\n");
+#endif
+                                               closesocket(ConnectSocket);
+                                               ConnectSocket = INVALID_SOCKET;
+                                               return;
+                                       }
+#ifdef _DEBUG
+                                       else
+                                               OutputDebugString(szError);
+#endif
+
+                               }
+
+                               SendMessage(hDlg, WM_COMMAND, 
MAKELONG(LOWORD(idButton), BN_CLICKED), (LONG)hButton);
+
+                               return;
+                       }
+               }
+               hWnd = GetWindow(hWnd, GW_HWNDNEXT);
+       }
+}
+
+//
+//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
+//
+//  PURPOSE:  Processes messages for the main window.
+//
+//  WM_COMMAND - process the application menu
+//  WM_PAINT   - Paint the main window
+//  WM_DESTROY - post a quit message and return
+//
+//
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+       int wmId, wmEvent;
+       PAINTSTRUCT ps;
+       HDC hdc;
+       TCHAR szHello[MAX_LOADSTRING];
+       LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
+
+       switch (message) 
+       {
+               case WM_COMMAND:
+                       wmId    = LOWORD(wParam); 
+                       wmEvent = HIWORD(wParam); 
+                       // Parse the menu selections:
+                       switch (wmId)
+                       {
+                               case IDM_ABOUT:
+                                  DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, 
hWnd, (DLGPROC)About);
+                                  break;
+                               case IDM_EXIT:
+                                  DestroyWindow(hWnd);
+                                  break;
+                               default:
+                                  return DefWindowProc(hWnd, message, wParam, 
lParam);
+                       }
+                       break;
+               case WM_PAINT:
+                       hdc = BeginPaint(hWnd, &ps);
+                       // TODO: Add any drawing code here...
+                       RECT rt;
+                       GetClientRect(hWnd, &rt);
+                       if (localIP)
+                               DrawText(hdc, localIP, strlen(localIP), &rt, 
DT_CENTER);
+                       EndPaint(hWnd, &ps);
+                       break;
+               case WM_TIMER:
+                       if (ConnectSocket == INVALID_SOCKET)
+                       {
+                               ConnectSocket = accept(ListenSocket, &connaddr, 
&addrlen);
+                               if (ConnectSocket != INVALID_SOCKET)
+                               {
+#ifdef _DEBUG
+                                               OutputDebugString("Connected to 
socket\n");
+#endif
+                               }
+                       }
+                       CheckForExceptionDialog(hWnd);
+                       break;
+               case WM_DESTROY:
+                       PostQuitMessage(0);
+                       break;
+               case EM_SETSEL:
+                       ConnectSocket = INVALID_SOCKET;
+                       break;
+               default:
+                       return DefWindowProc(hWnd, message, wParam, lParam);
+   }
+   return 0;
+}
+
+// Mesage handler for about box.
+LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+       switch (message)
+       {
+               case WM_INITDIALOG:
+                               return TRUE;
+
+               case WM_COMMAND:
+                       if (LOWORD(wParam) == IDOK || LOWORD(wParam) == 
IDCANCEL) 
+                       {
+                               EndDialog(hDlg, LOWORD(wParam));
+                               return TRUE;
+                       }
+                       break;
+       }
+    return FALSE;
+}
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsp
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsp
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsp
new file mode 100644
index 0000000..93d2a67
--- /dev/null
+++ 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsp
@@ -0,0 +1,140 @@
+# Microsoft Developer Studio Project File - 
Name="ContinueAfterRuntimeException" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=ContinueAfterRuntimeException - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ContinueAfterRuntimeException.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ContinueAfterRuntimeException.mak" 
CFG="ContinueAfterRuntimeException - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ContinueAfterRuntimeException - Win32 Release" (based on "Win32 
(x86) Application")
+!MESSAGE "ContinueAfterRuntimeException - Win32 Debug" (based on "Win32 (x86) 
Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ContinueAfterRuntimeException - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D 
"_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" 
/Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386
+
+!ELSEIF  "$(CFG)" == "ContinueAfterRuntimeException - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D 
"_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D 
"_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 
/pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ContinueAfterRuntimeException - Win32 Release"
+# Name "ContinueAfterRuntimeException - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\ContinueAfterRuntimeException.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ContinueAfterRuntimeException.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ContinueAfterRuntimeException.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\ContinueAfterRuntimeException.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\small.ico
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsw
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsw
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsw
new file mode 100644
index 0000000..128f914
--- /dev/null
+++ 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "ContinueAfterRuntimeException"=.\ContinueAfterRuntimeException.dsp - 
Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.h
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.h
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.h
new file mode 100644
index 0000000..84c0736
--- /dev/null
+++ 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if 
!defined(AFX_CONTINUEAFTERRUNTIMEEXCEPTION_H__DC8E8327_5E0B_4EE3_9891_6C46447FEBFD__INCLUDED_)
+#define 
AFX_CONTINUEAFTERRUNTIMEEXCEPTION_H__DC8E8327_5E0B_4EE3_9891_6C46447FEBFD__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h"
+
+
+#endif // 
!defined(AFX_CONTINUEAFTERRUNTIMEEXCEPTION_H__DC8E8327_5E0B_4EE3_9891_6C46447FEBFD__INCLUDED_)

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.rc
----------------------------------------------------------------------
diff --git 
a/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.rc
 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.rc
new file mode 100644
index 0000000..b6518fa
--- /dev/null
+++ 
b/mustella/src/main/flex/ContinueAfterRuntimeException/ContinueAfterRuntimeException.rc
@@ -0,0 +1,140 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_CONTINUEAFTERRUNTIMEEXCEPTION ICON    DISCARDABLE     
"ContinueAfterRuntimeException.ICO"
+IDI_SMALL               ICON    DISCARDABLE     "SMALL.ICO"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDC_CONTINUEAFTERRUNTIMEEXCEPTION MENU DISCARDABLE 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "E&xit",                       IDM_EXIT
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About ...",                  IDM_ABOUT
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDC_CONTINUEAFTERRUNTIMEEXCEPTION ACCELERATORS MOVEABLE PURE 
+BEGIN
+    "?",            IDM_ABOUT,              ASCII,  ALT
+    "/",            IDM_ABOUT,              ASCII,  ALT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE  22, 17, 230, 75
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "System"
+BEGIN
+    ICON            IDI_CONTINUEAFTERRUNTIMEEXCEPTION,IDC_MYICON,14,9,16,16
+    LTEXT           "ContinueAfterRuntimeException Version 1.0",IDC_STATIC,
+                    49,10,119,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2006",IDC_STATIC,49,20,119,8
+    DEFPUSHBUTTON   "OK",IDOK,195,6,30,11,WS_GROUP
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""resource.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_APP_TITLE           "ContinueAfterRuntimeException"
+    IDS_HELLO               "I watch for the Flash Player's\nexception dialog 
and will hit Continue\n when it appears."
+    IDC_CONTINUEAFTERRUNTIMEEXCEPTION "CONTINUEAFTERRUNTIMEEXCEPTION"
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/SMALL.ICO
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/ContinueAfterRuntimeException/SMALL.ICO 
b/mustella/src/main/flex/ContinueAfterRuntimeException/SMALL.ICO
new file mode 100644
index 0000000..3323086
Binary files /dev/null and 
b/mustella/src/main/flex/ContinueAfterRuntimeException/SMALL.ICO differ

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.cpp
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.cpp 
b/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.cpp
new file mode 100644
index 0000000..d90fe4a
--- /dev/null
+++ b/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.cpp
@@ -0,0 +1,26 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// stdafx.cpp : source file that includes just the standard includes
+//     ContinueAfterRuntimeException.pch will be the pre-compiled header
+//     stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.h
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.h 
b/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.h
new file mode 100644
index 0000000..68f06d7
--- /dev/null
+++ b/mustella/src/main/flex/ContinueAfterRuntimeException/StdAfx.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// stdafx.h : include file for standard system include files,
+//  or project specific include files that are used frequently, but
+//      are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
+#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define WIN32_LEAN_AND_MEAN            // Exclude rarely-used stuff from 
Windows headers
+
+
+// Windows Header Files:
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+// C RunTime Header Files
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+
+// Local Header Files
+
+// TODO: reference additional headers your program requires here
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before 
the previous line.
+
+#endif // 
!defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ContinueAfterRuntimeException/resource.h
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/ContinueAfterRuntimeException/resource.h 
b/mustella/src/main/flex/ContinueAfterRuntimeException/resource.h
new file mode 100644
index 0000000..475cd6c
--- /dev/null
+++ b/mustella/src/main/flex/ContinueAfterRuntimeException/resource.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by CONTINUEAFTERRUNTIMEEXCEPTION.RC
+//
+#define IDR_MAINFRAME                                  128
+#define IDD_CONTINUEAFTERRUNTIMEEXCEPTION_DIALOG               102
+#define IDD_ABOUTBOX                                   103
+#define IDS_APP_TITLE                                  103
+#define IDM_ABOUT                                              104
+#define IDM_EXIT                                               105
+#define IDS_HELLO                                              106
+#define IDI_CONTINUEAFTERRUNTIMEEXCEPTION                  107
+#define IDI_SMALL                                              108
+#define IDC_CONTINUEAFTERRUNTIMEEXCEPTION                  109
+#define IDC_MYICON                                             2
+#define IDC_STATIC                         -1
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           110
+#endif
+#endif

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/CoverageTimeout.as
----------------------------------------------------------------------
diff --git a/mustella/src/main/flex/CoverageTimeout.as 
b/mustella/src/main/flex/CoverageTimeout.as
new file mode 100644
index 0000000..01e6b75
--- /dev/null
+++ b/mustella/src/main/flex/CoverageTimeout.as
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.net.*;
+import flash.events.Event;
+
+[Mixin]
+/**
+ *  set a timeout to linger around for coverage data
+ */
+public class CoverageTimeout
+{
+
+       /**
+        *  Mixin callback that gets everything ready to go.
+        *  The UnitTester waits for an event before starting
+        */
+       public static function init(root:DisplayObject):void
+       {
+               UnitTester.coverageTimeout = 30000;
+       }
+
+
+}
+}

Reply via email to