<?xml version="1.0" encoding="utf-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->


<!--

This app should be used to create an Apache Flex SDK that has the
directory structure that an IDE expects.

The Adobe AIR SDK and the Adobe Flash Player playerglobal.swc are integrated
into the directory structure.  The paths in the framework configuration files are
modified to reflect this.  The AIR_HOME and PLAYERGLOBAL_HOME environment
variables are not required because the locations of these pieces are known.

-->


<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       width="800" height="700" maxWidth="800" maxHeight="700" minWidth="800" minHeight="700"
                       backgroundColor="0xDDDDDD"
                       preinitialize="getInvoke()"
                       applicationComplete="handleApplicationComplete(event)" showStatusBar="false"
                       skinClass="ws.tink.spark.skins.controls.InstallApacheFlexSkin"
                       xmlns:controls="ws.tink.spark.controls.*"
                       xmlns:controls1="org.apache.flex.packageflexsdk.view.controls.*"
                       xmlns:components="org.apache.flex.packageflexsdk.view.components.*"
                       xmlns:controls2="org.apache.flex.utilities.common.controls.*">
    
    <fx:Style source="assets/styles/ApacheFlexToolsStyle.css"/>
    <fx:Style source="assets/styles/InstallApacheFlexStyle.css"/> 
    
    <fx:Declarations>
        <fx:Component className="CacheDialog" >
            <s:TitleWindow title="Download Cache Configuration" width="400" height="130" 
                           backgroundColor="0xDDDDDD" close="closeUp()">
                 <fx:Script>
                     <![CDATA[
                     import mx.managers.PopUpManager;

                     private function browseFolders():void
                     {
                         var file:File;
                         if (folder.text.length > 0)
                             file = File.applicationStorageDirectory.resolvePath(folder.text);
                         else
                             file = File.applicationStorageDirectory;
                         file.browseForDirectory("Download Cache Folder");
                         file.addEventListener(Event.SELECT, folderSelected);
                     }

                     private function folderSelected(event:Event):void
                     {
                         folder.text = event.target.nativePath;
                     }

                     private function closeUp():void
                     {
                         PopUpManager.removePopUp(this);
                     }

                     private function updateCache():void
                     {
                         dispatchEvent(new Event(Event.COMPLETE));
                         closeUp();
                     }
                     ]]>
                 </fx:Script>
                <s:VGroup left="10" top="10" right="10">
                    <s:CheckBox id="cb" label="Cache Downloaded Files" />
                    <s:HGroup width="100%" verticalAlign="baseline">
                        <s:Label text="Cache Folder: " />
                        <s:TextInput id="folder" width="100%" enabled="{cb.selected}"/>
                        <s:Button label="Browse..." click="browseFolders()" styleName="genericBtnStyle" enabled="{cb.selected}"/>
                    </s:HGroup>
                    <s:HGroup horizontalAlign="center" width="100%" >
                        <s:Button label="OK" click="updateCache()" enabled="{cb.selected == false || folder.text.length > 0}" styleName="genericBtnStyle" />
                        <s:Button label="Cancel" click="closeUp()" styleName="genericBtnStyle" />
                    </s:HGroup>
                </s:VGroup>
            </s:TitleWindow>
        </fx:Component>
    </fx:Declarations>
     <fx:Script><![CDATA[
         import flash.globalization.LocaleID;
         import flash.globalization.StringTools;

         import mx.collections.ArrayCollection;
         import mx.core.IFlexDisplayObject;
         import mx.events.FlexEvent;
         import mx.events.PropertyChangeEvent;
         import mx.managers.CursorManager;
         import mx.managers.PopUpManager;
         import mx.resources.ResourceBundle;
         import mx.rpc.events.FaultEvent;
         import mx.rpc.events.ResultEvent;
         import mx.rpc.http.HTTPService;
         import mx.utils.StringUtil;

         import org.apache.flex.ant.Ant;
         import org.apache.flex.packageflexsdk.model.InstallerComponentVO;
         import org.apache.flex.packageflexsdk.model.OS;
         import org.apache.flex.packageflexsdk.resource.ViewResourceConstants;
         import org.apache.flex.packageflexsdk.util.CalcButtonWidth;
         import org.apache.flex.packageflexsdk.util.MD5CompareUtil;
         import org.apache.flex.packageflexsdk.view.UpdaterDialog;
         import org.apache.flex.packageflexsdk.view.components.AdobeLicense;
         import org.apache.flex.packageflexsdk.view.components.ConsoleWindow;
         import org.apache.flex.packageflexsdk.view.components.MPLLicense;
         import org.apache.flex.packageflexsdk.view.events.InstallItemSelectionEvent;
         import org.apache.flex.utilities.common.Constants;
         import org.apache.flex.utilities.common.MirrorURLUtil;
         import org.apache.flex.utilities.common.interfaces.ILog;
         import org.apache.flex.utilities.common.vo.LogMessagesVO;
         import org.as3commons.zip.Zip;
         import org.as3commons.zip.ZipEvent;
         import org.as3commons.zip.ZipFile;

         import spark.events.IndexChangeEvent;
         import spark.events.TextOperationEvent;

         import ws.tink.spark.controls.StepItem;
         import ws.tink.spark.skins.controls.InstallApacheFlexSkin;

         // embed us strings so we can always have them if we can't get to the locale files
         [Embed(source="properties/en_US.properties", mimeType="application/octet-stream")]
         private var en_US_Properties:Class;

         private var cleanedUp:Boolean;

         private var _mirrorURLCGI:String;
         private var _useMirror:Boolean = true;
         private var _latestVersion:String;
         private var loggedVersion:Boolean;
         private var logFile:String;
         private var debugMode:Boolean = false;
         private var logProgressEvents:Boolean = false;
         private var showDevBuilds:Boolean = false;
         private var usingDownloadCache:Boolean;
         private var downloadCacheFolder:String;
         private var userDefaultLanguage:String;
         private var firstTime:Boolean = true;
         private var legacy:Boolean = true;
         private var nocache:Boolean = true;
         private var wasAborted:Boolean;

         public var installerAppPath:String;
         public var installerAppFileName:String;

         // loader needs to be in instance var otherwise it can get GC'd.
         // We only load one thing at a time, so we can all share this
         // var
         private var loader:URLLoader;

         /**
          * Utility Singleton Instances
          */
         private var _md5CompareUtil:MD5CompareUtil = MD5CompareUtil.instance;
         private var _mirrorURLUtil:MirrorURLUtil = MirrorURLUtil.instance;

         /**
          * Apache Flex binary distribution
          *
          * Values stored in sdk-installer-config.xml edit file to change
          *
          */
         private var APACHE_FLEX_BIN_DISTRO_PATH:String;
         private var APACHE_FLEX_BIN_DISTRO_FILE:String;
         private var APACHE_FLEX_BIN_INSTALLER_FILE:String;
         private var APACHE_FLEX_BIN_DISTRO_FILE_SHORT:String;
         private var APACHE_FLEX_BIN_DISTRO_URL:String;
         private var APACHE_FLEX_BIN_INSTALLER_URL:String;
         [Bindable]
         private var APACHE_FLEX_BIN_DISTRO_VERSION:String = "";
         [Bindable]
         private var APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY:String = "";

         /**
          * Adobe AIR SDK
          *
          * Values stored in sdk-installer-config.xml edit file to change
          *
          */
         [Bindable]
         private var AIR_VERSIONS:ArrayCollection = new ArrayCollection();
         private var AIR_VERSION:String = "14.0";
         private var ADOBE_AIR_SDK_WIN_FILE:String;
         private var ADOBE_AIR_SDK_WIN_URL:String;
         private var ADOBE_AIR_SDK_MAC_FILE:String;
         private var ADOBE_AIR_SDK_MAC_URL:String;
         private var ADOBE_AIR_SDK_LINUX_FILE:String;
         private var ADOBE_AIR_SDK_LINUX_URL:String;

         /**
          * Adobe Flash Player
          *
          * Values stored in sdk-installer-config.xml edit file to change
          *
          */
         [Bindable]
         private var FLASH_PLAYER_VERSIONS:ArrayCollection = new ArrayCollection();
         private var FLASH_PLAYER_VERSION:String = "11.1";
         private var FLASH_PLAYER_SWF_VERSION:String = "14";
         private var ADOBE_FB_GLOBALPLAYER_SWC_FILE:String;
         private var ADOBE_FB_GLOBALPLAYER_SWC_URL:String;

         /**
          * Apache Flex
          *
          * Values stored in sdk-installer-config.xml edit file to change
          *
          */
         [Bindable]
         private var FLEX_VERSIONS:ArrayCollection = new ArrayCollection();

         /**
          *
          * SwfObject
          *
          */
         private var SWF_OBJECT_FILE:String;
         private var SWF_OBJECT_URL:String;

         /**
          * Optional installs
          *
          */
         private var OSMF_SWC_FILE:String;
         private var OSMF_SWC_URL:String;
         private var OSMF_SWF_FILE:String = "osmf.swf";

         private var BLAZEDS_FILE:String;
         private var BLAZEDS_URL:String;

         private var AFE_FILE:String;
         private var AFE_URL:String;
         private var AGLJ40_FILE:String;
         private var AGLJ40_URL:String;
         private var FLEX_FONTKIT_FILE:String;
         private var FLEX_FONTKIT_URL:String;
         private var RIDEAU_FILE:String;
         private var RIDEAU_URL:String;

         [Bindable]
         private var _flexHome:String;
         private var _flexTemp:String;
         private var _flexHomeDir:File;
         private var _flexTempDir:File;
         private var _apacheFlexSDKCompressedFile:File;
         private var _adobeAIRSDKZipFile:File;
         private var _fbGlobalPlayerDir:File;
         private var _fbGlobalPlayerFile:File;
         private var _blazeDSJarFile:File;
         private var _afeJarFile:File;
         private var _aglj40JarFile:File;
         private var _flexFontKitJarFile:File;
         private var _rideauJarFile:File;
         private var _osmfSWCFile:File;
         private var _osmfSWFFile:File;

         private var _os:OS = new OS();
         private var _loader:URLLoader;
         private var _process:NativeProcess;
         private var _previousDisplayedPercent:int = 0;
         private var _fileUnzipErrorFunction:Function;
         private var _numOptionalComponents:int = 4;
         private var _numOptionalComponentsPermissions:int = 0;
         private var _useOSMF2:Boolean = true;

         private var languageOverride:String;
         private var configOverride:String = "";
         private var stepsOverride:String = "";
         private var installOverride:String = "";

         private var overlaying:Boolean;
         private var usingXML:Object;
         private var additionalProps:Object = {};
         private var licensePropertyMap:Object = {};
         private var progressLabels:XML;
         private var installStepsData:XMLList;
         private var stepIDs:Vector.<String> = new Vector.<String>();
         private var stepLabels:Vector.<String> = new Vector.<String>();
         private var currentStep:int = 0;

         private var customMenuItem1:ContextMenuItem = new ContextMenuItem("Show Dev Builds");
         private var customMenuItem2:ContextMenuItem = new ContextMenuItem("Configure Download Cache...");
         private var customMenuItem3:ContextMenuItem = new ContextMenuItem("Enable Verbose Logging");
         private var customMenuItem4:ContextMenuItem = new ContextMenuItem("Enable Progress Logging");

         [Bindable]
         private var _viewResourceConstants:ViewResourceConstants;
         [Bindable]
         private var supportedLanguages:ArrayCollection = new ArrayCollection();
         [Bindable]
         private var _installationSteps:ArrayCollection = new ArrayCollection();
         [Bindable]
         private var _installerComponentsDataProvider:ArrayCollection = new ArrayCollection();
         [Bindable]
         private var _currentLicenseURL:String;
         [Bindable]
         private var _currentLicenseLabel:String;
         [Bindable]
         public var _messages:ArrayCollection = new ArrayCollection();

         private var _lastTag:String;
         private var _lastPublicMessage:String;
         public function set lastPublicMessage(s:String):void
         {
             var tag:String;
             var c:int;

             c = s.indexOf("[");
             if (c != -1)
             {
                 var c2:int = s.indexOf("] ");
                 if (c2 != -1)
                 {
                     tag = s.substring(c + 1, c2);
                     s = s.substr(c2 + 2);
                 }
             }
             if (tag && tag == _lastTag && tag == "get")
                 _lastPublicMessage += "\n" + s;
             else
                 _lastPublicMessage = s;
             _lastTag = tag;
             dispatchEvent(new Event("messageChanged"));
         }

         [Bindable("messageChanged")]
         public function get lastFilteredPublicMessage():String
         {
             return _lastPublicMessage;
         }

         private function getInvoke():void
         {
             var nativeApplication:NativeApplication = NativeApplication.nativeApplication;
             nativeApplication.addEventListener(InvokeEvent.INVOKE, parseArgs);
         }

         [Bindable]
         private var _standardButtonWidth:Number = 88;

         public function setButtonWidths():void
         {
             var calc:CalcButtonWidth = new CalcButtonWidth(hiddenButton);

             calc.buttonWidth(installLogBtn);
             calc.buttonWidth(openApacheFlexFolderBtn);

             _standardButtonWidth = calc.maxButtonWidth([installBtn, browseBtn, closeBtn, nextBtn, firstStepBackBtn, secondStepBackBtn]);
         }

         private function parseArgs(event:InvokeEvent):void
         {
             for each (var s:String in event.arguments)
             {
                 if (s.indexOf("-language=") == 0)
                 {
                     languageOverride = s.substring(10);
                 }
                 if (s.indexOf("-config=") == 0)
                 {
                     configOverride = s.substring(8);
                 }
                 if (s.indexOf("-install=") == 0)
                 {
                     installOverride = s.substring(9);
                 }
                 if (s.indexOf("-steps=") == 0)
                 {
                     stepsOverride = s.substring(7);
                 }
                 if (s.indexOf("-debug") == 0)
                 {
                     debugMode = true;
                 }
                 if (s.indexOf("-log=") == 0)
                 {
                     debugMode = true;
                     logFile = s.substring(5);
                 }
             }
             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
             usingDownloadCache = so.data.usingDownloadCache;
             downloadCacheFolder = so.data.downloadCacheFolder;
             userDefaultLanguage = so.data.userDefaultLanguage;
         }

         protected function handleApplicationComplete(event:FlexEvent):void
         {
             CursorManager.setBusyCursor();
             loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
             addEventListener(Event.CLOSING, closeApplication);
             updateWindow();
             var hasInternet:Boolean = false;
             var networkAdapters:Vector.<NetworkInterface> = NetworkInfo.networkInfo.findInterfaces();
             for each (var networkAdapter:NetworkInterface in networkAdapters)
             {
                 if (networkAdapter.active)
                 {
                     hasInternet = true;
                     break;
                 }
             }
             if (hasInternet)
             {
                 loadXML();
             }
             logVersion();
             if (!hasInternet)
             {
                 log("Internet connection unavailable");
                 abortInstallation("Internet connection unavailable.");
             }
         }

         private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
         {
             if (currentStep > 0)
                 updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
             if (event.error is Error)
             {
                 var error:Error = event.error as Error;
                 log(error.message);
                 log(error.getStackTrace(), -1, false);
                 abortInstallation(error.message + "\n" + error.getStackTrace());
             }
             else if (event.error is ErrorEvent)
             {
                 var errorEvent:ErrorEvent = event.error as ErrorEvent;
                 log(errorEvent.text);
                 abortInstallation(errorEvent.text);
             }
             else
             {
                 // a non-Error, non-ErrorEvent type was thrown and uncaught
                 log(event.toString());
                 abortInstallation(event.toString());
             }
         }

         /**
          * Define on ResourceManager all keys for translation.
          * If some key is not present on any other language selected by user, the default value will be displayed
          * on the screen
          */
         private function defineResourceManagerDefaultLanguage():void
         {
             selectDefaultLanguage();
         }

         private function getIndexOfEnUS():int
         {
             for (var i:int = 0; i < _langSelect.dataProvider.length; i++)
             {
                 if (_langSelect.dataProvider.getItemAt(i).data == "en_US")
                 {
                     return i;
                 }
             }
             return -1;
         }

         private function updateWindowTitle():void
         {
             if (_viewResourceConstants)
                 this.nativeWindow.title = StringUtil.substitute(_viewResourceConstants.INFO_WINDOW_TITLE, [APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY]);
         }

         protected function selectDefaultLanguageInEmergency():void
         {
             loadLanguage("en_US", loadUSInEmergencyComplete);
         }

         private function loadUSInEmergencyComplete():void
         {
             _viewResourceConstants = ViewResourceConstants.instance;
             _viewResourceConstants.update();
         }

         protected function selectDefaultLanguage():void
         {
             loadLanguage("en_US", loadUSComplete);
         }

         private function loadUSComplete():void
         {
             var userLocale:String;

             if (userDefaultLanguage)
             {
                 userLocale = userDefaultLanguage;
             }
             else
             {
                 userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
             }

             if (languageOverride)
             {
                 userLocale = languageOverride;
             }

             loadDefaultLanguage(userLocale);
         }

         private function loadDefaultLanguage(userLocale:String):void
         {
             loadLanguage(userLocale, defaultLanguageLoaded);
         }

         private var languageURL:String;
         private var languageID:String;

         private function loadLanguage(userLocale:String, completeFunction:Function):void
         {
             if (languageURL && loader) // busy loading another language
                 loader.close();

             if (userLocale == "en_US")
             {
                 var ba:ByteArray = new en_US_Properties() as ByteArray;
                 var data:String = ba.readUTFBytes(ba.bytesAvailable);
                 installLanguage(userLocale, data);
                 completeFunction();
                 return;
             }
             var n:int = supportedLanguages.length;
             for (var i:int = 0; i < n; i++)
             {
                 if (supportedLanguages[i].data == userLocale)
                 {
                     languageID = userLocale;
                     languageURL = supportedLanguages[i].path;
                     var url:URLRequest = new URLRequest(languageURL);
                     loader = new URLLoader();
                     loader.dataFormat = URLLoaderDataFormat.TEXT;
                     loader.addEventListener(IOErrorEvent.IO_ERROR, languageLoadErrorHandler);
                     loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, languageLoadErrorHandler);
                     loader.addEventListener(Event.COMPLETE, function (e:Event):void
                     {
                         languageURL = null;
                         installLanguage(userLocale, loader.data);
                         completeFunction();
                     });
                     loader.load(url);
                     return;
                 }
             }
             completeFunction();
         }

         private function installLanguage(userLocale:String, data:String):void
         {
             var resource:ResourceBundle = new ResourceBundle(userLocale, ViewResourceConstants.BUNDLE_NAME);
             var variables:Array;
             if (data.indexOf("\r\n") != -1)
                 variables = data.split("\r\n");
             else
                 variables = data.split("\n");
             for each (var p:String in variables)
             {
                 if (p.charAt(0) == "#")
                     continue;

                 var c:int = p.indexOf("=");
                 if (c != -1)
                 {
                     var key:String = p.substr(0, c);
                     var value:String = p.substr(c + 1);
                     while (value.indexOf("\\n") != -1)
                         value = value.replace("\\n", "\n");
                     resource.content[key] = value;
                 }
             }

             resourceManager.addResourceBundle(resource);
         }

         private function languageLoadErrorHandler(event:Event):void
         {
             log("Unable to load language file " + languageURL);
             log(event.toString());
             abortInstallation("Unable to load language file " + languageURL);
         }

         private function defaultLanguageLoaded():void
         {
             resourceManager.localeChain = [ViewResourceConstants.DEFAULT_LANGUAGE];

             var userLocale:String;

             if (userDefaultLanguage)
             {
                 userLocale = userDefaultLanguage;
             }
             else
             {
                 userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
             }

             if (languageOverride)
             {
                 userLocale = languageOverride;
             }
             log("Using Locale: " + userLocale);

             var n:int = supportedLanguages.length;
             for (var i:int = 0; i < n; i++)
             {
                 if (supportedLanguages[i].data == userLocale)
                 {
                     _langSelect.selectedIndex = i;

                     resourceManager.localeChain = [userLocale, "en_US"];

                     break;
                 }
             }
             _viewResourceConstants = ViewResourceConstants.instance;

             resourceManager.addEventListener(Event.CHANGE, _viewResourceConstants.update);

             _viewResourceConstants.update();
             setButtonWidths();
             directoryBtn.enabled = true;

             updateWindow();

             _mirrorURLUtil.logMessages = new LogMessagesVO(_viewResourceConstants.FETCH_MIRROR_CGI, _viewResourceConstants.FETCH_MIRROR_CGI_DONE,
                     _viewResourceConstants.FETCH_MIRROR_CGI_ERROR);

             _mirrorURLUtil.getMirrorURL(Constants.APACHE_FLEX_URL + _mirrorURLCGI, getMirrorURLResultHandler);
             CursorManager.removeBusyCursor();

             checkValidOS();
         }

         protected function updateWindow():void
         {
             updateWindowTitle();

             this.nativeWindow.x = Screen.mainScreen.bounds.width / 2 - this.nativeWindow.width / 2;
             this.nativeWindow.y = Screen.mainScreen.bounds.height / 2 - this.nativeWindow.height / 2;
         }

         protected function loadXML():void
         {
             var request:URLRequest;

             if (configOverride != "")
             {
                 request = new URLRequest(configOverride);
             }
             else
             {
                 request = new URLRequest(Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
             }

             _loader = new URLLoader();

             try
             {
                 _loader.load(request);
             }
             catch (error:Error)
             {
                 selectDefaultLanguageInEmergency();
                 log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
                 log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + error.errorID + " " + error.message);
                 abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
             }

             _loader.addEventListener(IOErrorEvent.IO_ERROR, xmlError, false, 0, true);
             _loader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);
         }

         protected function xmlError(event:IOErrorEvent):void
         {
             selectDefaultLanguageInEmergency();
             log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
             log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + event.errorID);
             abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME + " " + event.toString());
         }

         protected function xmlLoaded(event:Event):void
         {
             if (setXMLVariables())
             {
                 _langSelect.dataProvider = supportedLanguages;
                 _langSelect.selectedIndex = getIndexOfEnUS();
                 _langSelect.enabled = true;
                 defineResourceManagerDefaultLanguage();
             }
         }

         protected function checkValidOS():void
         {
             if (_os.isOther())
                 log(_viewResourceConstants.ERROR_UNSUPPORTED_OPERATING_SYSTEM);
         }

         private function devBuildFilterFunction(o:Object):Boolean
         {
             return !o.devBuild;
         }

         private function debugModeHandler(event:Event):void
         {
             debugMode = true;
             customMenuItem3.caption = "Verbose Logging Enabled";
         }

         private function debugProgressHandler(event:Event):void
         {
             logProgressEvents = true;
             customMenuItem4.caption = "Logging Progress Events";
         }

         private function devBuildShowHandler(event:Event):void
         {
             var item:Object = flexVersion.selectedItem;
             FLEX_VERSIONS.filterFunction = null;
             FLEX_VERSIONS.refresh();
             flexVersion.selectedItem = item;
             customMenuItem1.caption = "Showing Dev Builds";
         }

         private function downloadCacheHandler(event:Event):void
         {
             var dlg:CacheDialog = new CacheDialog();
             dlg.addEventListener(Event.COMPLETE, updateDownloadCache);
             PopUpManager.addPopUp(dlg, this, true);
             PopUpManager.centerPopUp(dlg);
             dlg.cb.selected = usingDownloadCache;
             dlg.folder.text = downloadCacheFolder;
         }

         private function updateDownloadCache(event:Event):void
         {
             downloadCacheFolder = event.target.folder.text;
             usingDownloadCache = event.target.cb.selected;
             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
             so.data.usingDownloadCache = usingDownloadCache;
             so.data.downloadCacheFolder = downloadCacheFolder;
             so.flush();
         }

         protected function setXMLVariables():Boolean
         {
             try
             {
                 var data:XML = XML(_loader.data);
             }
             catch (e:Error)
             {
                 log("Error parsing configuration file");
                 abortInstallation("Error parsing configuration file");
                 return false;
             }
             var keepGoing:Boolean = true;
             if (firstTime)
             {
                 firstTime = false;

                 _latestVersion = data.version.latest.toString();

                 installerAppPath = data.installer.(@name == 'SDKInstallerApp').@path.toString();
                 installerAppFileName = data.installer.(@name == 'SDKInstallerApp').@file.toString();

                 _mirrorURLCGI = data.mirror.(@name == 'MirrorURLCGI').@file.toString();

                 customMenuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, devBuildShowHandler);
                 customMenuItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, downloadCacheHandler);
                 customMenuItem3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugModeHandler);
                 customMenuItem4.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugProgressHandler);

                 var contextMenuCustomItems:Array = ContextMenu(contextMenu).customItems;
                 contextMenuCustomItems.push(customMenuItem1);
                 contextMenuCustomItems.push(customMenuItem2);
                 contextMenuCustomItems.push(customMenuItem3);
                 contextMenuCustomItems.push(customMenuItem4);

                 var name:String;
                 var versionString:String;
                 var versionID:String;

                 var languages:XMLList = data.languages.children();
                 for each (var lang:XML in languages)
                 {
                     var item:Object = {
                         label: lang.@name.toString(),
                         data: lang.@id.toString(),
                         path: lang.@path.toString()
                     };
                     supportedLanguages.addItem(item);
                 }

                 var airData:XMLList = data.airsdk[_os.os].versions;
                 var airVersionList:XMLList = airData[0].children();
                 var airVersions:Array = [];
                 var selected:String = airData[0]["@default"].toString();
                 for each (var airVersion:XML in airVersionList)
                 {
                     var displayVersion:String = airVersion.@displayVersion.toString();
                     versionString = airVersion.@version.toString();
                     versionID = null;
                     if (airVersion.@versionID.length() > 0)
                         versionID = airVersion.@versionID.toString();
                     airVersions.push(versionString);
                     var airPath:String = airVersion.path.toString();
                     var airFile:String = airVersion.file.toString();
                     AIR_VERSIONS.addItem({
                         label: "AIR " + displayVersion, version: versionString, versionID: versionID,
                         path: airPath, file: airFile
                     });
                 }

                 if (this.airVersion.selectedIndex == -1)
                 {
                     this.airVersion.selectedIndex = airVersions.indexOf(selected);
                 }

                 var flexData:XMLList = data.products.children();
                 var selectedFlexVersion:int;
                 for each (var productData:XML in flexData)
                 {
                     var productName:String = productData.@name.toString();
                     var productPrefix:String = productData.@prefix.toString();
                     var productVersionList:XMLList = productData.versions.children();
                     var isOverlay:Boolean = productData.@overlay.toString() == "true";
                     var needsAIR:Boolean = productData.@needsAIR.toString() != "false";
                     var needsFlash:Boolean = productData.@needsFlash.toString() != "false";
                     var icon:String = productData.@icon.toString();
                     for each (var productVersion:XML in productVersionList)
                     {
                         var shortName:String = productVersion.@file.toString();
                         var fileName:String = shortName + (_os.isWindows() ? Constants.ARCHIVE_EXTENSION_WIN : Constants.ARCHIVE_EXTENSION_MAC);
                         versionString = productVersion.@version.toString();
                         var label:String = productName + " " + versionString;
                         var ver:String = fileName.substr(productPrefix.length).split("-")[0];
                         var path:String = productVersion.@path.toString();
                         var devBuild:Boolean = productVersion.@dev.toString() == "true";
                         var legacy:Boolean = productVersion.@legacy.toString() == "true";
                         var nocache:Boolean = productVersion.@nocache.toString() == "true";
                         if (productVersion["@default"].length() == 1)
                             selectedFlexVersion = FLEX_VERSIONS.length;
                         FLEX_VERSIONS.addItem({
                             shortName: shortName, fileName: fileName, label: label, version: ver,
                             path: path, overlay: isOverlay, prefix: productPrefix, legacy: legacy, nocache: nocache,
                             needsAIR: needsAIR, needsFlash: needsFlash, devBuild: devBuild, icon: icon
                         });
                     }
                 }

                 FLEX_VERSIONS.filterFunction = devBuildFilterFunction;
                 FLEX_VERSIONS.refresh();
                 flexVersion.validateNow();

                 if (this.flexVersion.selectedIndex == -1)
                 {
                     this.flexVersion.selectedIndex = selectedFlexVersion;
                 }

                 var selectedFlexVersionObject:Object = this.flexVersion.selectedItem;
                 updateFlexVersionStrings(selectedFlexVersionObject);

                 if (!APACHE_FLEX_BIN_DISTRO_FILE || !APACHE_FLEX_BIN_DISTRO_PATH)
                 {
                     log(_viewResourceConstants.ERROR_INVALID_SDK_URL);
                     keepGoing = false;
                 }

                 var flashData:XMLList = data.flashsdk.versions;
                 var flashVersionList:XMLList = flashData[0].children();
                 var flashPlayerVersions:Array = [];
                 selected = flashData[0]["@default"].toString();
                 for each (var flashVersion:XML in flashVersionList)
                 {
                     displayVersion = flashVersion.@displayVersion.toString();
                     versionString = flashVersion.@version.toString();
                     versionID = null;
                     if (flashVersion.@versionID.length() > 0)
                         versionID = flashVersion.@versionID.toString();
                     flashPlayerVersions.push(versionString);
                     if (!_os.isLinux() || Number(versionString) <= 11.2)
                     {
                         var swfVersion:String = flashVersion.swfversion.toString();
                         var flashPath:String = flashVersion.path.toString();
                         var flashFile:String = flashVersion.file.toString();
                         FLASH_PLAYER_VERSIONS.addItem({
                             label: "Flash Player " + displayVersion, version: versionString, swfVersion: swfVersion,
                             versionID: versionID, path: flashPath, file: flashFile
                         });
                     }
                 }

                 if (this.flashPlayerVersion.selectedIndex == -1)
                 {
                     this.flashPlayerVersion.selectedIndex = flashPlayerVersions.indexOf(selected);
                 }
             }

             ADOBE_AIR_SDK_WIN_FILE = data.airsdk.windows.versions.children().(@version == AIR_VERSION).file.toString();
             ADOBE_AIR_SDK_WIN_URL = data.airsdk.windows.versions.children().(@version == AIR_VERSION).path.toString();
             if (_os.isWindows() && (!ADOBE_AIR_SDK_WIN_FILE || !ADOBE_AIR_SDK_WIN_URL))
             {
                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_WINDOWS);
                 keepGoing = false;
             }
             ADOBE_AIR_SDK_WIN_URL += ADOBE_AIR_SDK_WIN_FILE;

             ADOBE_AIR_SDK_MAC_FILE = data.airsdk.mac.versions.children().(@version == AIR_VERSION).file.toString();
             ADOBE_AIR_SDK_MAC_URL = data.airsdk.mac.versions.children().(@version == AIR_VERSION).path.toString();
             if (_os.isMac() && (!ADOBE_AIR_SDK_MAC_FILE || !ADOBE_AIR_SDK_MAC_URL))
             {
                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_MAC);
                 keepGoing = false;
             }
             ADOBE_AIR_SDK_MAC_URL += ADOBE_AIR_SDK_MAC_FILE;

             ADOBE_AIR_SDK_LINUX_FILE = data.airsdk.linux.versions.children().(@version == AIR_VERSION).file.toString();
             ADOBE_AIR_SDK_LINUX_URL = data.airsdk.linux.versions.children().(@version == AIR_VERSION).path.toString();
             if (_os.isLinux() && (!ADOBE_AIR_SDK_LINUX_FILE || !ADOBE_AIR_SDK_LINUX_URL))
             {
                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_LINUX);
                 keepGoing = false;
             }
             ADOBE_AIR_SDK_LINUX_URL += ADOBE_AIR_SDK_LINUX_FILE;

             ADOBE_FB_GLOBALPLAYER_SWC_FILE = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).file.toString();
             ADOBE_FB_GLOBALPLAYER_SWC_URL = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).path.toString();
             FLASH_PLAYER_SWF_VERSION = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).swfversion.toString();
             if (!ADOBE_FB_GLOBALPLAYER_SWC_FILE || !ADOBE_FB_GLOBALPLAYER_SWC_URL)
             {
                 log(_viewResourceConstants.ERROR_INVALID_FLASH_PLAYER_SWC_URL);
                 keepGoing = false;
             }
             ADOBE_FB_GLOBALPLAYER_SWC_URL += ADOBE_FB_GLOBALPLAYER_SWC_FILE;

             SWF_OBJECT_FILE = data.swfobject.@file.toString();
             SWF_OBJECT_URL = data.swfobject.@path.toString();

             //Supporting OSMF 2.0 from 4.11 onwards.  
             if (APACHE_FLEX_BIN_DISTRO_VERSION == "4.9.1" || APACHE_FLEX_BIN_DISTRO_VERSION == "4.10.0")
             {
                 OSMF_SWC_FILE = data.OSMF_SWC.@file.toString();
                 OSMF_SWC_URL = data.OSMF_SWC.@path.toString();
                 _useOSMF2 = false;
             }
             else
             {
                 OSMF_SWC_FILE = data["OSMF_SWC_2.0"].@file.toString();
                 OSMF_SWC_URL = data["OSMF_SWC_2.0"].@path.toString();
                 _useOSMF2 = true;
             }

             BLAZEDS_FILE = data.BlazeDS.@file.toString();
             BLAZEDS_URL = data.BlazeDS.@path.toString();

             AFE_FILE = data.fontswf.afe.@file.toString();
             AFE_URL = data.fontswf.afe.@path.toString();

             AGLJ40_FILE = data.fontswf.aglj40.@file.toString();
             AGLJ40_URL = data.fontswf.aglj40.@path.toString();

             FLEX_FONTKIT_FILE = data.fontswf["flex-fontkit"].@file.toString();
             FLEX_FONTKIT_URL = data.fontswf["flex-fontkit"].@path.toString();

             RIDEAU_FILE = data.fontswf.rideau.@file.toString();
             RIDEAU_URL = data.fontswf.rideau.@path.toString();


             return keepGoing;
         }

         protected function updateFlexVersionStrings(selectedFlexVersionObject:Object):void
         {
             APACHE_FLEX_BIN_DISTRO_FILE_SHORT = selectedFlexVersionObject.shortName;
             APACHE_FLEX_BIN_DISTRO_VERSION = selectedFlexVersionObject.version;
             APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = selectedFlexVersionObject.label;

             APACHE_FLEX_BIN_DISTRO_FILE = selectedFlexVersionObject.fileName;
             APACHE_FLEX_BIN_DISTRO_PATH = selectedFlexVersionObject.path;
             legacy = selectedFlexVersionObject.legacy;
             nocache = selectedFlexVersionObject.nocache;
             APACHE_FLEX_BIN_INSTALLER_FILE = selectedFlexVersionObject.prefix + "installer-config.xml";

             // ApacheFlex is full URL so download directly and dont use mirror useful for testing release candidates
             if (APACHE_FLEX_BIN_DISTRO_PATH.indexOf("http") == 0)
             {
                 _useMirror = false;
             }
             else
             {
                 _useMirror = true;
             }
         }

         private function useMirrorPath(path:String):String
         {
             if (_useMirror)
             {
                 return path;
             }

             return "";
         }

         private function getMirrorURLResultHandler():void
         {
             var logMessages:ArrayCollection = ILog(_mirrorURLUtil).log;
             var i:int;
             var n:int = logMessages.length;
             for (i = 0; i < n; i++)
             {
                 log(String(logMessages.getItemAt(i)));
             }

             if (_mirrorURLUtil.errorOccurred)
             {
                 abortInstallation("mirrorURLUtil.errorOccurred");
                 main();
             }
             else
             {
                 updatePaths();
             }

         }

         protected function updatePaths():void
         {
             if (APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.URL_PREFIX.length) == Constants.URL_PREFIX
                     || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.FILE_PREFIX.length) == Constants.FILE_PREFIX
                     || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.HTTPS_PREFIX.length) == Constants.HTTPS_PREFIX)
             {
                 APACHE_FLEX_BIN_DISTRO_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
                 if (stepsOverride != "")
                 {
                     APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
                 }
                 else
                 {
                     APACHE_FLEX_BIN_INSTALLER_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
                 }
             }
             else
             {
                 APACHE_FLEX_BIN_DISTRO_URL = useMirrorPath(_mirrorURLUtil.mirrorURL) + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
                 if (stepsOverride != "")
                 {
                     APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
                 }
                 else
                 {
                     APACHE_FLEX_BIN_INSTALLER_URL = MD5CompareUtil.MD5_DOMAIN + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
                 }
             }

             if (installerAppPath.substr(0, Constants.URL_PREFIX.length) != Constants.URL_PREFIX)
             {
                 installerAppPath = useMirrorPath(_mirrorURLUtil.mirrorURL) + installerAppPath;
             }

             main();
         }

         protected function main():void
         {

             if (shouldUpdate())
             {
                 doUpdate();
             }
         }

         private function logVersion():void
         {
             if (!loggedVersion)
             {
                 //Current version
                 var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
                 var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
                 var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();

                 // Log the Installer version to help with any support issues that arise.
                 log("Installer version " + currentVersion + " (" + _os.os + ")", 0);
                 loggedVersion = true;
             }
         }

         protected function shouldUpdate():Boolean
         {
             var shouldUpdate:Boolean = false;
             //Current version
             var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
             var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
             var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();

             logVersion();

             var availBuildNumbers:Array = _latestVersion.split(".");
             var currentBuildNumbers:Array = currentVersion.split(".");

             if (parseInt(availBuildNumbers[0]) > parseInt(currentBuildNumbers[0]))
             {
                 return true;
             }
             else if (parseInt(availBuildNumbers[0]) == parseInt(currentBuildNumbers[0]))
             {
                 if (parseInt(availBuildNumbers[1]) > parseInt(currentBuildNumbers[1]))
                 {
                     return true;
                 }
                 else if (parseInt(availBuildNumbers[1]) == parseInt(currentBuildNumbers[1]))
                 {
                     if (parseInt(availBuildNumbers[2]) > parseInt(currentBuildNumbers[2]))
                     {
                         return true;
                     }
                 }
             }
             return false;

         }

         protected function doUpdate():void
         {
             var updaterDialog:UpdaterDialog = UpdaterDialog(PopUpManager.createPopUp(this, UpdaterDialog, true));
             updaterDialog.addEventListener("close", handleUpdaterDialogClose);
             updaterDialog.latestVersion = _latestVersion;
             PopUpManager.centerPopUp(updaterDialog);
         }

         protected function handleUpdaterDialogClose(event:Event):void
         {
             PopUpManager.removePopUp(IFlexDisplayObject(event.target));
         }

         protected function handleInstallBtnClick(event:MouseEvent):void
         {
             var airVersionID:String = airVersion.selectedItem.versionID;
             var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;

             log("SDK version " + APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY);

             if (flexVersion.selectedItem.needsAIR)
             {
                 if (airVersionID)
                     log("AIR version " + airVersionID);
                 else
                     log("AIR version " + AIR_VERSION);
             }

             if (flexVersion.selectedItem.needsFlash)
             {
                 if (flashVersionID)
                     log("Flash Player version " + flashVersionID);
                 else
                     log("Flash Player version " + FLASH_PLAYER_VERSION);
             }

             if (flexSDKTxtInput.text == "")
             {
                 log(_viewResourceConstants.INFO_ENTER_VALID_FLEX_SDK_PATH);
             }
             else
             {
                 _langSelect.enabled = false;
                 _flexHome = flexSDKTxtInput.text;
                 resetInstallStepsActivity();
                 addOptionalComponentsToInstallSteps();
                 this.currentState = "installState";
                 install();
             }
         }

         protected function handleZeroStepNextBtnClick(event:MouseEvent):void
         {
             directoryBtn.enabled = false;

             AIR_VERSION = airVersion.selectedItem.version;
             var airVersionID:String = airVersion.selectedItem.versionID;
             FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
             var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;

             setXMLVariables(); // as AIR and Flash version may of changed

             if (!legacy)
             {
                 var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
                 loader = new URLLoader();
                 loader.dataFormat = URLLoaderDataFormat.TEXT;
                 loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
                 loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
                 loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallerXMLError);

                 loader.load(req);
             }
             else
             {
                 showDirectoryState();
             }
         }

         protected function handleFirstStepBackBtnClick(event:MouseEvent):void
         {
             showDefaultState();
         }

         protected function handleSecondStepBackBtnClick(event:MouseEvent):void
         {
             showDirectoryState();
         }

         protected function handleFirstStepNextBtnClick(event:MouseEvent):void
         {
             // Quick check to see if the selected directory is writable
             try
             {
                 var f:File = new File(_flexHome + File.separator + "flex.txt");
                 checkDirWritable(f);
             }
             catch (e:Error)
             {
                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
                 flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
                 return;
             }

             showOptionsState();
         }

         protected function handleInstallerXMLLoaded(event:Event):void
         {
             var data:XML = XML(event.target.data);
             var localeList:Array = resourceManager.localeChain;
             _installerComponentsDataProvider = new ArrayCollection();
             var compList:XMLList = data.component;
             for each (var comp:XML in compList)
             {
                 var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
                         getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
                         getLocalizedString(comp, "licenseURL"),
                         comp.@id.toString(), comp.@required.toString() == "true");
                 licensePropertyMap[comp.@property.toString()] = vo;
                 _installerComponentsDataProvider.addItem(vo);
             }
             usingXML = true;
             // progressLabels = data.progressLabels[0];
             installStepsData = data.steps.step;
             var strings:XMLList = data.strings.string;
             for each (var x:XML in strings)
             {
                 var id:String = x.@id.toString();
                 if (id in _viewResourceConstants)
                 {
                     var val:String = getLocalizedString(x, null);
                     _viewResourceConstants[id] = val;
                     var pce:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, id, "", val);
                     _viewResourceConstants.dispatchEvent(pce);
                 }
             }
             var props:XMLList = data.properties.property;
             for each (x in props)
             {
                 additionalProps[x.@name.toString()] = x.@value.toString();
             }
             currentState = "directoryState";
         }

         private function getLocalizedString(xml:XML, propName:String):String
         {
             var compBundle:XMLList;
             for each (var locale:String in resourceManager.localeChain)
             {
                 compBundle = xml[locale];
                 if (compBundle.length() == 1)
                 {
                     if (propName)
                     {
                         var xmlList:XMLList = compBundle[0][propName];
                         if (xmlList.length() == 1)
                         {
                             return xmlList[0].toString();
                         }
                     }
                     else
                     {
                         var s:String = compBundle[0].toString();
                         if (s.length > 0)
                             return s;
                     }
                 }
             }
             return "";
         }

         protected function handleInstallerXMLError(event:Event):void
         {
             log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
             abortInstallation("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
         }

         protected function showDefaultState():void
         {
             zeroStepGroup.visible = true;
             directoryBtn.enabled = true;
             currentState = "default";
         }

         protected function showDirectoryState():void
         {
             initiateInstallStepsActivity();
             if (currentState != "optionsState")
             {
                 initializeInstallerComponentsDataProvider();
             }
             currentState = "directoryState";
         }

         protected function showOptionsState():void
         {
             currentState = "optionsState";
             checkIfAllRequiredComponentsPromptsAnswered();
         }

         protected function initiateInstallStepsActivity():void
         {
             _installationSteps = new ArrayCollection();

             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT));
             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF));
         }

         protected function resetInstallStepsActivity():void
         {
             for each(var step:StepItem in _installationSteps)
             {
                 step.status = StepItem.NORMAL;
             }
         }

         protected function addOptionalComponentsToInstallSteps():void
         {
             if (usingXML)
             {
                 _installationSteps = new ArrayCollection();

                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));

                 for each (var stepData:XML in installStepsData)
                 {
                     var propName:String = stepData.@property.toString();
                     if (!propName || InstallerComponentVO(licensePropertyMap[propName]).selected)
                     {
                         var si:StepItem = new StepItem(getLocalizedString(stepData, null));
                         _installationSteps.addItem(si);
                         stepIDs.push(stepData.@id.toString());
                         stepLabels.push(si.label);
                     }
                 }
                 return;
             }
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (!obj.required && obj.selected)
                 {
                     _installationSteps.addItem(new StepItem(obj.label));
                 }
             }
         }

         protected function initializeInstallerComponentsDataProvider():void
         {
             _installerComponentsDataProvider = new ArrayCollection();
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK,
                     _viewResourceConstants.ASK_APACHE_FLEX, _viewResourceConstants.LICENSE_APACHE_V2,
                     _viewResourceConstants.LICENSE_URL_APACHE_V2,
                     "STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK", true));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK,
                     _viewResourceConstants.ASK_ADOBE_AIR_SDK,
                     _viewResourceConstants.LICENSE_ADOBE_AIR_SDK,
                     _viewResourceConstants.LICENSE_URL_ADOBE_AIR_SDK,
                     "STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK", true));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC,
                     _viewResourceConstants.ASK_ADOBE_FLASH_PLAYER_GLOBAL_SWC,
                     _viewResourceConstants.LICENSE_ADOBE_SDK,
                     _viewResourceConstants.LICENSE_URL_ADOBE_SDK,
                     "STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC", true));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT,
                     _viewResourceConstants.ASK_SWFOBJECT, _viewResourceConstants.LICENSE_SWFOBJECT,
                     _viewResourceConstants.LICENSE_URL_SWFOBJECT, "STEP_REQUIRED_INSTALL_SWFOBJECT",
                     true));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF,
                     _viewResourceConstants.ASK_OSMF, _viewResourceConstants.LICENSE_OSMF,
                     _viewResourceConstants.LICENSE_URL_OSMF, "STEP_REQUIRED_INSTALL_OSMF", true));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF,
                     _viewResourceConstants.ASK_FONTSWF, _viewResourceConstants.LICENSE_FONTSWF,
                     _viewResourceConstants.LICENSE_URL_FONTSWF, "STEP_OPTIONAL_INSTALL_FONTSWF",
                     false));
             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS,
                     _viewResourceConstants.ASK_BLAZEDS, _viewResourceConstants.LICENSE_BLAZEDS,
                     _viewResourceConstants.LICENSE_URL_BLAZEDS, "STEP_OPTIONAL_INSTALL_BLAZEDS",
                     false));
         }

         protected function install():void
         {
             createDirectories();
         }

         protected function handleAirVersionChange(event:Event):void
         {
             AIR_VERSION = airVersion.selectedItem.version;

             // Match AIR and Flash versions
             if (flashPlayerVersion.selectedIndex != airVersion.selectedIndex)
             {
                 flashPlayerVersion.selectedIndex = airVersion.selectedIndex;
                 FLASH_PLAYER_VERSION = FLASH_PLAYER_VERSIONS[airVersion.selectedIndex].version;
             }
         }

         protected function handleFlashPlayerVersionChange(event:Event):void
         {
             FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;

             // Match AIR and Flash versions
             if (airVersion.selectedIndex != flashPlayerVersion.selectedIndex)
             {
                 airVersion.selectedIndex = flashPlayerVersion.selectedIndex;
                 AIR_VERSION = AIR_VERSIONS[flashPlayerVersion.selectedIndex].version;
             }
         }

         protected function handleFlexVersionChange(event:Event):void
         {
             var item:Object = flexVersion.selectedItem;
             airVersion.enabled = item.needsAIR;
             flashPlayerVersion.enabled = item.needsFlash;
             updateFlexVersionStrings(item);
             updatePaths();
             updateWindowTitle();
             InstallApacheFlexSkin(skin).textIcon.source = item.icon;
         }

         protected function browseForSDK(event:MouseEvent):void
         {
             var file:File = new File();

             file.addEventListener(Event.SELECT, flexSDKDirSelected, false, 0, true);
             file.browseForDirectory(_viewResourceConstants.INFO_SELECT_DIRECTORY);
         }

         protected function checkDirWritable(file:File):void
         {
             var ba:ByteArray = new ByteArray();
             ba.writeUTFBytes("1");
             writeFileToDirectory(file, ba);
             file.deleteFile();
         }

         protected function flexSDKDirSelected(event:Event):void
         {
             var selectedDir:File = File(event.target);
             var overlay:Boolean = flexVersion.selectedItem.overlay;

             // Quick check to see if the selected directory is writable
             try
             {
                 var f:File = new File(selectedDir.nativePath + File.separator + "flex.txt");
                 checkDirWritable(f);
             }
             catch (e:Error)
             {
                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
                 log(_viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS);
                 flexSDKTxtInput.text = selectedDir.nativePath;
                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS + " : " + selectedDir.nativePath; // tooltip
                 flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS; // field
                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
                 return;
             }

             overlaying = overlay;
             if (!overlay)
             {
                 if (isDirectoryEmpty(selectedDir))
                 {
                     _flexHome = selectedDir.nativePath;
                     flexSDKTxtInput.text = _flexHome;
                     nextBtn.enabled = true;
                     _langSelect.enabled = true;
                     flexSDKTxtInput.errorString = "";
                     flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
                 }
                 else
                 {
                     nextBtn.enabled = false;
                     flexSDKTxtInput.text = selectedDir.nativePath;
                     flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_NOT_EMPTY + " : " + selectedDir.nativePath;
                     flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_NOT_EMPTY;
                 }
             }
             else
             {
                 _flexHome = selectedDir.nativePath;
                 flexSDKTxtInput.text = _flexHome;
                 nextBtn.enabled = true;
                 _langSelect.enabled = true;
                 flexSDKTxtInput.errorString = "";
                 flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
             }
         }

         protected function handleFlexSDXTxtInputChange(event:TextOperationEvent):void
         {
             var tempDir:File;
             var path:String = flexSDKTxtInput.text;

             try
             {
                 tempDir = new File(path);

                 if (isDirectoryEmpty(tempDir))
                 {
                     flexSDKTxtInput.errorString = "";
                     _flexHome = path;
                     nextBtn.enabled = true;
                     _langSelect.enabled = true;
                 }
                 else
                 {
                     flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
                     nextBtn.enabled = false;
                 }
             }
             catch (e:Error)
             {
                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
                 nextBtn.enabled = false;
             }
         }

         protected function createDirectories():void
         {
             updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ACTIVE);

             try
             {
                 if (!overlaying)
                     log(_viewResourceConstants.INFO_CREATING_FLEX_HOME);
                 _flexHomeDir = createFolder(_flexHome);
                 log(_viewResourceConstants.INFO_CREATING_TEMP_DIR);
                 _flexTemp = _flexHome + File.separator + "temp";
                 _flexTempDir = createFolder(_flexTemp);
                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.COMPLETE);
                 downloadApacheFlexSDK();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
                 abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
             }
         }

         protected function downloadApacheFlexSDK():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_DOWNLOADING_FLEX_SDK + APACHE_FLEX_BIN_DISTRO_URL);
                 _apacheFlexSDKCompressedFile = File.userDirectory.resolvePath(_flexTemp + File.separator + APACHE_FLEX_BIN_DISTRO_FILE);
                 copyOrDownload(APACHE_FLEX_BIN_DISTRO_URL, handleApacheFlexSDKDownload, _apacheFlexSDKCompressedFile, handleApacheFlexSDKDownloadError, nocache);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
                 abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
             }

         }

         protected function handleApacheFlexSDKDownload(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_apacheFlexSDKCompressedFile, event.target.data);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
                 abortInstallation("handleApacheFlexSDKDownload " + e.message);
             }

             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.COMPLETE);

             updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ACTIVE);

             log(_viewResourceConstants.STEP_VERIFY_FLEX_SDK);

             _md5CompareUtil.addEventListener(ProgressEvent.PROGRESS, md5VerificationProgressHandler);
             _md5CompareUtil.verifyMD5(_apacheFlexSDKCompressedFile, APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE, uncompressApacheFlexSDK);
         }

         protected function md5VerificationProgressHandler(event:ProgressEvent):void
         {
             if (logProgressEvents)
                 log("md5 progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
             if (event.bytesTotal > 0)
                 progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
         }

         protected function handleApacheFlexSDKDownloadError(event:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
             abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
         }

         protected function uncompressApacheFlexSDK():void
         {
             if (!_md5CompareUtil.fileIsVerified)
             {
                 updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ERROR);

                 log(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);

                 abortInstallation(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
                 return;
             }
             else
             {
                 updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);

                 log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
             }

             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);

                 if (_os.isWindows())
                 {
                     unzip(_apacheFlexSDKCompressedFile, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
                 }
                 else
                 {
                     untar(_apacheFlexSDKCompressedFile, _flexTempDir, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
                 }
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
                 abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + e.message);
             }
         }

         protected function handleApacheFlexSDKZipFileUnzipComplete(event:Event):void
         {
             log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.COMPLETE);

             if (_os.isWindows())
             {
                 if (usingXML)
                     runInstallerScript();
                 else
                     downloadAIRRuntimeKitForWindows();
             }
             else
             {
                 if (!overlaying)
                 {
                     /* Copy all files from the unarchived directory to the root */
                     var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
                     var files:Array = directory.getDirectoryListing();
                     for each(var file:File in files)
                     {
                         file.copyTo(_flexHomeDir.resolvePath(file.name));
                     }
                 }
                 if (usingXML)
                 {
                     runInstallerScript();
                 }
                 else
                 {
                     if (_os.isMac())
                     {
                         downloadAIRRuntimeKitForMac();
                     }
                     else
                     {
                         downloadAIRRuntimeKitForLinux();
                     }
                 }
             }
         }

         protected function handleApacheFlexSDKZipFileUnzipError(error:ErrorEvent = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
             abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + error.toString());
         }

         protected function runInstallerScript():void
         {
             ant = new Ant();
             ant.output = output;

             var file:File;
             if (installOverride != "")
             {
                 file = new File(installOverride);
             }
             else if (overlaying)
             {
                 var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
                 if (_os.isWindows())
                 {
                     file = _flexTempDir.resolvePath("installer.xml");
                 }
                 else
                 {
                     file = directory.resolvePath("installer.xml");
                 }
             }
             else
             {
                 file = _flexHomeDir.resolvePath("installer.xml");
             }
             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
             var context:Object = {installer: true};
             if (usingDownloadCache)
             {
                 context["usingDownloadCache"] = usingDownloadCache;
                 context["downloadCacheFolder"] = downloadCacheFolder;
             }
             if (configOverride != "")
             {
                 context["xml.properties"] = configOverride;
             }
             if (resourceManager.localeChain.length > 1)
             {
                 context["bundle"] = resourceManager.localeChain[0];
             }
             for (var p:String in licensePropertyMap)
             {
                 if (InstallerComponentVO(licensePropertyMap[p]).selected)
                     context[p] = true;
             }
             for (p in additionalProps)
                 context[p] = additionalProps[p];

             context["air.sdk.version"] = AIR_VERSION;
             if (airVersion.selectedItem.versionID)
                 context["air.sdk.versionID"] = airVersion.selectedItem.versionID;
             context["air.sdk.url.path"] = airVersion.selectedItem.path;
             context["air.sdk.url.file"] = airVersion.selectedItem.file;
             context["flash.sdk.version"] = FLASH_PLAYER_VERSION;
             if (flashPlayerVersion.selectedItem.versionID)
                 context["flash.sdk.versionID"] = flashPlayerVersion.selectedItem.versionID;
             if (debugMode)
                 context["verbose"] = true;
             if (flashPlayerVersion.selectedItem.path)
             {
                 context["flash.sdk.url.path"] = flashPlayerVersion.selectedItem.path;
                 context["flash.sdk.url.file"] = flashPlayerVersion.selectedItem.file;
             }

             if (file.exists && !ant.processXMLFile(file, context, true))
             {
                 ant.addEventListener(Event.COMPLETE, completeHandler);
                 ant.addEventListener(ProgressEvent.PROGRESS, progressEventHandler);
             }
             else
                 completeHandler(null);
         }

         private function progressEventHandler(event:ProgressEvent):void
         {
             if (logProgressEvents)
                 log("progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
             if (event.bytesTotal > 0)
                 progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
             /*
              if (ant.progressClass is Copy)
              {
              progressBar.label = getLocalizedString(progressLabels, "Copy");
              }
              else if (ant.progressClass is Get)
              {
              progressBar.label = getLocalizedString(progressLabels, "Get");
              }
              else if (ant.progressClass is Checksum)
              {
              progressBar.label = getLocalizedString(progressLabels, "Checksum");
              }
              */
         }

         private function completeHandler(event:Event):void
         {
             if (Ant.currentAnt && !Ant.currentAnt.project.status)
             {
                 var msg:String = Ant.currentAnt.project.failureMessage;
                 log(msg ? msg : "no failure message provided");
                 if (currentStep > 0)
                     updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
             }
             else if (currentStep == stepLabels.length && currentStep > 0)
                 updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);

             if (Ant.currentAnt)
             {
                 if (Ant.currentAnt.project.status)
                     tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
                 if (Ant.currentAnt.project.failureMessage)
                     cleanup(!Ant.currentAnt.project.status, "&info=" + escape(Ant.currentAnt.project.failureMessage));
                 else
                     cleanup(!Ant.currentAnt.project.status);
             }
             else
             {
                 cleanup();
             }
         }

         private var ant:Ant;

         private function output(s:String):void
         {
             var isPublic:Boolean = false;
             var skipLog:Boolean = !debugMode;
             if (s.indexOf(":") != -1 && s.charAt(0) == "\n")
             {
                 // target output is a newline then the target name then a colon
                 if (currentStep < stepLabels.length && "\n" + stepIDs[currentStep] + ":" == s)
                 {
                     if (currentStep > 0)
                         updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
                     if (currentStep < stepLabels.length)
                         updateActivityStep(stepLabels[currentStep++], StepItem.ACTIVE);
                 }
                 isPublic = false;
             }
             else if (s.indexOf("[echo] ") != -1)
             {
                 s = s.substr(s.indexOf("[echo] ") + 7);
                 isPublic = true;
                 skipLog = false;
             }
             else if (s.indexOf("[fail] ") != -1)
             {
                 s = s.substr(s.indexOf("[fail] ") + 7);
                 isPublic = true;
                 skipLog = false;
             }
             log(s, -1, isPublic, skipLog);
         }

         private function enterFrameHandler(event:Event):void
         {
             ant.doCallback();
         }

         protected function downloadAIRRuntimeKitForWindows():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_WINDOWS + ADOBE_AIR_SDK_WIN_URL);
                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_WIN_FILE);
                 copyOrDownload(ADOBE_AIR_SDK_WIN_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function downloadAIRRuntimeKitForMac():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_MAC_URL);
                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_MAC_FILE);
                 copyOrDownload(ADOBE_AIR_SDK_MAC_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function downloadAIRRuntimeKitForLinux():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_LINUX_URL);
                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_LINUX_FILE);
                 copyOrDownload(ADOBE_AIR_SDK_LINUX_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function handleAIRSDKDownload(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_adobeAIRSDKZipFile, event.target.data);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
                 abortInstallation();
             }

             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.COMPLETE);

             unzipAdobeAIRSDK();
         }

         protected function handleAIRSDKDownloadError(error:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_AIR_SDK);
             abortInstallation();
         }

         protected function unzipAdobeAIRSDK():void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ACTIVE);

             try
             {
                 if (_os.isWindows())
                 {
                     unzipAdobeAIRSDKWindows()
                 }
                 else
                 {
                     unzipAdobeAIRSDKMac();
                 }
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function unzipAdobeAIRSDKWindows():void
         {
             log(_viewResourceConstants.INFO_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
             unzip(_adobeAIRSDKZipFile, handleAdobeAIRSDKWinZipFileUnzipComplete, handleAdobeAIRSDKWinZipFileUnzipError);
         }

         protected function unzipAdobeAIRSDKMac():void
         {
             if (NativeProcess.isSupported)
             {
                 untar(_adobeAIRSDKZipFile, _flexHomeDir, handleAdobeAIRSDKMacUntarComplete, handleAdobeAIRSDKMacUntarError);
             }
             else
             {
                 log(_viewResourceConstants.ERROR_NATIVE_PROCESS_NOT_SUPPORTED);
                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
             }
         }

         protected function handleAdobeAIRSDKMacUntarError(error:ProgressEvent = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
             abortInstallation();
         }

         protected function handleAdobeAIRSDKMacUntarComplete(event:Event):void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
             log(_viewResourceConstants.INFO_FINISHED_UNTARING + _adobeAIRSDKZipFile.nativePath);
             downloadPlayerGlobalSWC();
         }

         protected function handleAdobeAIRSDKWinZipFileUnzipComplete(event:Event):void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
             log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
             downloadPlayerGlobalSWC();
         }

         protected function handleAdobeAIRSDKWinZipFileUnzipError(error:ErrorEvent = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
         }

         protected function downloadPlayerGlobalSWC():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ACTIVE);

             try
             {
                 log(_viewResourceConstants.INFO_INSTALLING_PLAYERGLOBAL_SWC + ADOBE_FB_GLOBALPLAYER_SWC_URL);
                 _fbGlobalPlayerDir = createFolder(_flexHome + File.separator + "frameworks" + File.separator + "libs" + File.separator + "player"
                 + File.separator + FLASH_PLAYER_VERSION);
                 _fbGlobalPlayerFile = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
                 copyOrDownload(ADOBE_FB_GLOBALPLAYER_SWC_URL, handlePlayerGlobalDownload, _fbGlobalPlayerFile, handlePlayerGlobalDownloadError);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function handlePlayerGlobalDownload(event:Event):void
         {
             try
             {
                 var playerGlobalFile:File = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
                 writeFileToDirectory(playerGlobalFile, event.target.data);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
                 abortInstallation();
             }
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.COMPLETE);
             copyConfigFiles();
         }

         protected function handlePlayerGlobalDownloadError(event:ErrorEvent = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLASH_PLAYER_SWC);
             abortInstallation();
         }

         protected function changeConfig(frameworksDir:File, file:File, flashPlayerVersion:String, swfVersion:String):void
         {
             if (isValidConfigFile(file))
             {
                 var configFile:FileStream = new FileStream();
                 configFile.open(file, FileMode.READ);
                 var contents:String = configFile.readMultiByte(configFile.bytesAvailable, "utf-8");
                 var playerVersion:RegExp = /<target-player>\d\d\.\d<\/target-player>/;
                 contents = contents.replace(playerVersion, "<target-player>" + flashPlayerVersion + "<\/target-player>");
                 var playerSwfVersion:RegExp = /<swf-version>\d\d<\/swf-version>/;
                 contents = contents.replace(playerSwfVersion, "<swf-version>" + swfVersion + "<\/swf-version>");
                 configFile.close();
                 configFile.open(file, FileMode.WRITE);
                 configFile.writeMultiByte(contents, "utf-8");
                 var copyToFile:File = frameworksDir.resolvePath(file.name);
                 configFile.close();
                 file.copyTo(copyToFile, true);
             }
         }

         protected function copyConfigFiles():void
         {
             var aborted:Boolean = false;

             updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ACTIVE);

             try
             {
                 //Config files
                 var configFilesDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "ide" + File.separator + "flashbuilder" + File.separator
                 + "config");
                 var configFiles:Array = configFilesDir.getDirectoryListing();
                 var flexHomeFrameworksDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "frameworks");
                 log(_viewResourceConstants.INFO_INSTALLING_CONFIG_FILES);

                 for each (var file:File in configFiles)
                 {
                     changeConfig(flexHomeFrameworksDir, file, FLASH_PLAYER_VERSION, FLASH_PLAYER_SWF_VERSION);
                 }

                 file = File.userDirectory.resolvePath(_flexHome + File.separator + "flex-sdk-description.xml");
                 var descriptionFile:FileStream = new FileStream();
                 descriptionFile.open(file, FileMode.READ);
                 var contents:String = descriptionFile.readMultiByte(descriptionFile.bytesAvailable, "utf-8");
                 var description:RegExp = /<name>[^<]*<\/name>/;
                 contents = contents.replace(description, "<name>Apache Flex " + APACHE_FLEX_BIN_DISTRO_VERSION + " FP " + FLASH_PLAYER_VERSION + " AIR " + AIR_VERSION + " en_US</name>");
                 descriptionFile.close();
                 descriptionFile.open(file, FileMode.WRITE);
                 descriptionFile.writeMultiByte(contents, "utf-8");
                 descriptionFile.close();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ERROR);
                 log(_viewResourceConstants.ERROR_UNABLE_TO_INSTALL_CONFIG_FILES);
                 abortInstallation();
                 aborted = true;
             }

             if (!aborted)
             {
                 updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.COMPLETE);
                 downloadSwfObject();
             }
         }

         protected function downloadSwfObject():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ACTIVE);

             try
             {
                 log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [SWF_OBJECT_FILE, SWF_OBJECT_URL]));
                 copyOrDownload(SWF_OBJECT_URL + SWF_OBJECT_FILE, handlSWFObjectDownload, null, handleSWFObjectDownloadError);
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
                 abortInstallation();
             }
         }

         protected function handlSWFObjectDownload(event:Event):void
         {
             log(_viewResourceConstants.INFO_DOWNLOADED);
             var swfObjectZipFile:File = File.userDirectory.resolvePath(_flexTemp + File.separator + SWF_OBJECT_FILE);
             writeFileToDirectory(swfObjectZipFile, event.target.data);
             unzip(swfObjectZipFile, handleSWFObjectUnzipComplete, handleSWFObjectZipFileUnzipError);
         }

         protected function handleSWFObjectDownloadError(event:ErrorEvent = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
             abortInstallation();
         }

         protected function handleSWFObjectUnzipComplete(event:Event):void
         {
             try
             {
                 var expressInstallFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "expressInstall.swf");
                 expressInstallFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "expressInstall.swf"));

                 var swfObjectJSFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "swfobject.js");
                 swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "swfobject.js"));

                 swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("javascript" + File.separator + "FABridge" + File.separator + "samples" + File.separator
                 + "fabridge" + File.separator + "swfobject" + File.separator + "swfobject.js"));

                 var swfObjectDir:File = _flexHomeDir.resolvePath("swfobject");
                 swfObjectDir.deleteDirectory(true);

                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.COMPLETE);
                 installOSMF();

             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
                 log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
                 abortInstallation();
             }

         }

         protected function handleSWFObjectZipFileUnzipError(event:Event):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
             abortInstallation();
         }

         protected function installNextOptionalComponent():void
         {
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (obj.selected && !obj.installed && !obj.aborted)
                 {
                     switch (obj.label)
                     {
                         case _viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS:
                         {
                             installBlazeDS();
                             return;
                             break;
                         }
                         case _viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF:
                         {
                             installFontSwf();
                             return;
                             break;
                         }
                         default:
                         {
                             break;
                         }
                     }
                 }
             }
             checkAndHandleAllOptionalComponentsInstalled();
         }

         protected function installBlazeDS():void
         {
             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ACTIVE);
             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [BLAZEDS_FILE, BLAZEDS_URL]));
             _blazeDSJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + BLAZEDS_FILE);
             copyOrDownload(BLAZEDS_URL + BLAZEDS_FILE, handleBlazeDSDownloadComplete, null, handleBlazeDSInstallError);
         }

         protected function handleBlazeDSDownloadComplete(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_blazeDSJarFile, event.target.data);
                 copyFileToOptionalLibDir(_blazeDSJarFile);
                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, false);
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.COMPLETE);
                 clearData(URLLoader(event.target));
                 installNextOptionalComponent();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
                 installNextOptionalComponent();
             }
         }

         protected function installFontSwf():void
         {
             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ACTIVE);
             downloadFontSwfAFEFile();
         }

         protected function downloadFontSwfAFEFile():void
         {
             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AFE_FILE, AFE_URL]));
             _afeJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AFE_FILE);
             copyOrDownload(AFE_URL + AFE_FILE, handleFontSWFAFEFileDownloaded, null, handleFontSWFInstallError);
         }

         protected function handleFontSWFAFEFileDownloaded(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_afeJarFile, event.target.data);
                 copyFileToOptionalLibDir(_afeJarFile);
                 clearData(URLLoader(event.target));

                 downloadFontSwfAGLFile();

             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
                 installNextOptionalComponent();
             }
         }

         protected function downloadFontSwfAGLFile():void
         {
             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AGLJ40_FILE, AGLJ40_URL]));
             _aglj40JarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AGLJ40_FILE);
             copyOrDownload(AGLJ40_URL + AGLJ40_FILE, handleFontSWFAGLFileDownloaded, null, handleFontSWFInstallError);
         }

         protected function handleFontSWFAGLFileDownloaded(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_aglj40JarFile, event.target.data);
                 copyFileToOptionalLibDir(_aglj40JarFile);
                 clearData(URLLoader(event.target));

                 downloadFontSwfFlexFontKitFile();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
                 installNextOptionalComponent();
             }
         }

         protected function downloadFontSwfFlexFontKitFile():void
         {
             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [FLEX_FONTKIT_FILE, FLEX_FONTKIT_URL]));
             _flexFontKitJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + FLEX_FONTKIT_FILE);
             copyOrDownload(FLEX_FONTKIT_URL + FLEX_FONTKIT_FILE, handleFontSWFFlexFontKitFileDownloaded, null, handleFontSWFInstallError);
         }

         protected function handleFontSWFFlexFontKitFileDownloaded(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_flexFontKitJarFile, event.target.data);
                 copyFileToOptionalLibDir(_flexFontKitJarFile);
                 clearData(URLLoader(event.target));

                 downloadFontSwfRideauKitFile();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
                 installNextOptionalComponent();
             }
         }

         protected function downloadFontSwfRideauKitFile():void
         {
             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [RIDEAU_FILE, RIDEAU_URL]));
             _rideauJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + RIDEAU_FILE);
             copyOrDownload(RIDEAU_URL + RIDEAU_FILE, handleFontSWFRideauFileDownloaded, null, handleFontSWFInstallError);
         }

         protected function handleFontSWFRideauFileDownloaded(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_rideauJarFile, event.target.data);
                 copyFileToOptionalLibDir(_rideauJarFile);
                 clearData(URLLoader(event.target));

                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, false);
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.COMPLETE);
                 installNextOptionalComponent();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
                 installNextOptionalComponent();
             }
         }

         protected function installOSMF():void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ACTIVE);
             downloadOSMFFile();
         }

         protected function downloadOSMFFile():void
         {
             _osmfSWFFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWF_FILE.toLowerCase());

             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [OSMF_SWC_FILE, OSMF_SWC_URL]));
             _osmfSWCFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWC_FILE.toLowerCase());
             if (_useOSMF2)
             {
                 downloadOSMF2SWC();
             }
             else
             {
                 copyOrDownload(OSMF_SWC_URL + OSMF_SWC_FILE, handleOSMFSWCFileDownloaded, null, handleOSMFSWCInstallError);
             }
         }

         protected function downloadOSMF2SWC():void
         {
             var url:String;
             var httpService:HTTPService = new HTTPService();
             httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
             url = httpService.url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
             if (usingDownloadCache)
             {
                 var cacheURL:String;
                 if (url.indexOf("http") == 0)
                 {
                     var c:int = url.indexOf("/");
                     c = url.indexOf("/", c + 1);
                     c = url.indexOf("/", c + 1);
                     // that should find the slash after the server.
                     cacheURL = url.substr(c + 1);
                     if (debugMode)
                         log("http caching.  url = " + cacheURL);
                 }
                 var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                 cacheFile = cacheFile.resolvePath(escape(cacheURL));
                 if (debugMode)
                     log("searching cache for " + cacheFile.url);
                 if (cacheFile.exists)
                 {
                     if (debugMode)
                         log("found file in cache");
                     url = cacheFile.url;
                     actuallyDownloadOSMF2SWC(new URLRequest(url));
                     return;
                 }
             }
             httpService.addEventListener(ResultEvent.RESULT, getMirrorInfo);
             httpService.addEventListener(FaultEvent.FAULT, handleOSMFSWCUnzipError);
             httpService.send();
         }

         protected function getMirrorInfo(event:ResultEvent):void
         {
             var mirror:String = String(event.result);
             mirror = mirror.substr(mirror.indexOf('use_mirror=') + 'use_mirror='.length, mirror.length);
             mirror = mirror.substring(0, mirror.indexOf('">'));

             var mirrorURL:String = 'http://' + mirror + Constants.SOURCEFORGE_DL_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
             var refererURL:String = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + '/download?use_mirror=' + mirror;

             var req:URLRequest = new URLRequest(mirrorURL);
             req.requestHeaders = [new URLRequestHeader('Referer', refererURL)];

             actuallyDownloadOSMF2SWC(req);
         }

         protected function actuallyDownloadOSMF2SWC(req:URLRequest):void
         {
             loader = new URLLoader();
             loader.dataFormat = URLLoaderDataFormat.BINARY;
             if (usingDownloadCache)
                 loader.addEventListener(Event.COMPLETE, cacheOSMF2SWC);
             loader.addEventListener(Event.COMPLETE, handleOSMFSWCFileDownloaded);
             loader.addEventListener(ErrorEvent.ERROR, handleOSMFSWCInstallError);
             loader.addEventListener(IOErrorEvent.IO_ERROR, handleOSMFSWCInstallError);

             loader.load(req);
         }

         protected function cacheOSMF2SWC(event:Event):void
         {
             var url:String;
             url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
             var cacheURL:String;
             if (url.indexOf("http") == 0)
             {
                 var c:int = url.indexOf("/");
                 c = url.indexOf("/", c + 1);
                 c = url.indexOf("/", c + 1);
                 // that should find the slash after the server.
                 cacheURL = url.substr(c + 1);
                 if (debugMode)
                     log("http caching.  url = " + cacheURL);
             }
             if (cacheURL)
             {
                 var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                 cacheFile = cacheFile.resolvePath(escape(cacheURL));
                 if (debugMode)
                     log("caching " + cacheFile.url);
                 if (!cacheFile.exists)
                 {
                     var fs:FileStream = new FileStream();
                     fs.open(cacheFile, FileMode.WRITE);
                     var srcData:ByteArray = ByteArray(loader.data);
                     srcData.position = 0;
                     var ba:ByteArray = new ByteArray();
                     srcData.readBytes(ba, 0, srcData.length);
                     ba.position = 0;
                     fs.writeBytes(ba, 0, ba.length);
                     fs.close();
                 }
                 else
                 {
                     if (debugMode)
                         log("file was already in cache");
                 }
             }
         }

         protected function handleOSMFSWCFileDownloaded(event:Event):void
         {
             try
             {
                 writeFileToDirectory(_osmfSWCFile, event.target.data);
                 copyFileToLibDir(_osmfSWCFile);
                 unzip(_osmfSWCFile, handleOSMFSWCUnzipped, handleOSMFSWCUnzipError);
                 clearData(URLLoader(event.target));

                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, false);
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.COMPLETE);
                 installNextOptionalComponent();
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
                 abortInstallation();
             }
         }

         /**
          * Unzip osmf.swc, extract library.swf from it and copy it into frameworks/rsls/osmf_<flexversion>.<buildnumber>
          * Delete other files extracted from osmf.swc
          */
         protected function handleOSMFSWCUnzipped(event:Event):void
         {
             try
             {
                 var osmfFileName:String = "osmf_" + getFlexVersionBuildString() + ".swf";
                 var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "rsls" + File.separator + osmfFileName);
                 var osmfLibrarySwfFile:File = _flexHomeDir.resolvePath("library.swf");
                 osmfLibrarySwfFile.moveTo(copyToFile);
                 var catalogXMLFile:File = _flexHomeDir.resolvePath("catalog.xml");
                 if (catalogXMLFile.exists)
                 {
                     catalogXMLFile.deleteFile();
                 }
                 var manifestXMLFile:File = _flexHomeDir.resolvePath("manifest.xml");
                 if (manifestXMLFile.exists)
                 {
                     manifestXMLFile.deleteFile();
                 }
             }
             catch (e:Error)
             {
                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
                 abortInstallation();
             }
         }

         protected function handleOSMFSWCUnzipError(event:Event):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
             abortInstallation();
         }

         protected function copyFileToOptionalLibDir(file:File):void
         {
             //Copy to "${FLEX_HOME}/lib/external/optional"
             var copyToFile:File = _flexHomeDir.resolvePath("lib" + File.separator + "external" + File.separator + "optional" + File.separator + file.name);
             file.copyTo(copyToFile, true);
         }

         protected function copyFileToLibDir(file:File):void
         {
             //Copy to "${FLEX_HOME}/frameworks/libs/"
             var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "libs" + File.separator + file.name);
             file.copyTo(copyToFile, true);
         }

         protected function handleBlazeDSInstallError(event:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["BlazeDS"]));
             installNextOptionalComponent();
         }

         protected function handleFontSWFInstallError(event:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["FontSwf Utility"]));
             installNextOptionalComponent();
         }

         protected function handleOSMFSWFInstallError(event:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWF"]));
             installNextOptionalComponent();
         }

         protected function handleOSMFSWCInstallError(event:* = null):void
         {
             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWC"]));
             installNextOptionalComponent();
         }

         protected function updateOptionalComponentInstallStatus(label:String, isInstalled:Boolean):void
         {
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (obj.label == label)
                 {
                     obj.installed = isInstalled;
                 }
             }
         }

         protected function updateOptionalComponentInstallStatusAborted(label:String, isAborted:Boolean):void
         {
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (obj.label == label)
                 {
                     obj.aborted = isAborted;
                 }
             }
         }

         protected function checkAndHandleAllOptionalComponentsInstalled():void
         {
             var allComponentsInstalled:Boolean = true;
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (!obj.required && obj.selected && !(obj.installed || obj.aborted))
                 {
                     allComponentsInstalled = false;
                 }
             }
             if (allComponentsInstalled)
             {
                 tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
                 cleanup(false);
             }
         }

         protected function cleanup(isAbort:Boolean = false, abortInfo:String = ""):void
         {
             if (cleanedUp)
                 return;

             cleanedUp = true;

             CursorManager.removeBusyCursor();
             if (!_viewResourceConstants)
             {
                 selectDefaultLanguageInEmergency();
             }
             try
             {
                 if (_flexTempDir)
                 {
                     _flexTempDir.deleteDirectory(true);
                 }
             }
             catch (e:Error)
             {
                 log(_viewResourceConstants.ERROR_UNABLE_TO_DELETE_TEMP_DIRECTORY);
             }

             if (isAbort)
             {
                 tracker.trackInstallerFailure(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION,
                         _os.os + "&info=" + abortInfo);
             }
             else if (!wasAborted)
             {
                 log(_viewResourceConstants.INFO_INSTALLATION_COMPLETE);
                 updateUIHandleInstallationComplete();
             }

             saveLogToDisk();
         }

         protected function saveLogToDisk():void
         {
             if (!_flexHomeDir)
             {
                 return;
             }

             var file:File = _flexHomeDir.resolvePath("installer.log");
             var fs:FileStream = new FileStream();

             try
             {
                 fs.open(file, FileMode.WRITE);
                 for each (var message:String in _messages)
                 {
                     fs.writeUTFBytes(message);
                     fs.writeUTFBytes("\n");
                 }
                 fs.close();
             }
             catch (e:Error)
             {
                 // TODO log error?
             }
         }

         protected function updateUIHandleInstallationComplete():void
         {
             browseBtn.enabled = true;
             openApacheFlexFolderBtn.visible = true;
             openApacheFlexFolderBtn.includeInLayout = true;
             progressBar.visible = false;
             progressBar.includeInLayout = false;
             thirdStepGroup.title = _viewResourceConstants.INFO_INSTALLATION_COMPLETE;
         }

         protected function abortInstallation(reason:String = ""):void
         {
             if (currentState != "installState")
                 showConsole(null);

             directoryBtn.enabled = false;
             browseBtn.enabled = false;
             installBtn.enabled = false;
             wasAborted = true;
             if (_viewResourceConstants)
                 log(_viewResourceConstants.INFO_ABORT_INSTALLATION);
             cleanup(true, reason);
             if (_viewResourceConstants)
                 firstStepGroup.title = secondStepGroup.title = thirdStepGroup.title = _viewResourceConstants.INFO_ABORT_INSTALLATION;
         }

         protected function _langSelect_changeHandler(event:IndexChangeEvent):void
         {
             var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;

             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
             so.data.userDefaultLanguage = _langSelect.selectedItem["data"];
             so.flush();

             if (_langSelect.selectedItem["data"] == defaultLanguage)
             {
                 resourceManager.localeChain = [defaultLanguage];
                 resourceManager.update();
                 setButtonWidths();
             }
             else
             {
                 loadLanguage(_langSelect.selectedItem["data"], _langSelect_changeCompleteHandler);
             }
         }

         private function _langSelect_changeCompleteHandler():void
         {
             var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
             resourceManager.localeChain = [languageID, defaultLanguage];
             resourceManager.update();
             log("Using Locale: " + languageID);
             setButtonWidths();
         }

         override protected function resourcesChanged():void
         {
             super.resourcesChanged();

             if (_viewResourceConstants)
             {
                 rememberInstallerComponents();
                 updateWindowTitle();
                 initiateInstallStepsActivity();
                 initializeInstallerComponentsDataProvider();
                 recallInstallerComponents();
             }
         }

         private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;

         protected function rememberInstallerComponents():void
         {
             _selectedInstallerComponents = new Vector.<InstallerComponentVO>;
             for each(var item:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (item.selected)
                 {
                     _selectedInstallerComponents.push(item);
                 }
             }
         }

         protected function recallInstallerComponents():void
         {
             for each(var item:InstallerComponentVO in _selectedInstallerComponents)
             {
                 getInstallerComponentFromLabel(item.key).selected = true;
             }
         }

         protected function placeGroup(panel:Panel):void
         {
             panel.x = this.width / 2 - panel.width / 2;
         }

         protected function handleOptionalInstallsChange(event:IndexChangeEvent):void
         {
             var selectedItem:InstallerComponentVO = InstallerComponentVO(event.target.selectedItem);
             optionalInstallsTxtArea.text = selectedItem.message;
             /*installChkBx.label = _viewResourceConstants.INSTALL_AGREE;
              if (selectedItem.answered) {
              if (selectedItem.selected) {
              installChkBx.selected = true;
              } else {
              installChkBx.selected = false;
              }
              } else {
              installChkBx.selected = false;
              }*/

             licenseLinkBtn.includeInLayout = true;
             _currentLicenseLabel = selectedItem.licenseName;
             _currentLicenseURL = selectedItem.licenseURL;
             checkIfAllRequiredComponentsPromptsAnswered();

         }

         protected function handleLicenceBtnClick(event:Event):void
         {
             navigateToURL(new URLRequest(_currentLicenseURL), "_blank");
         }

         protected function handleInstallPermissionChange(event:InstallItemSelectionEvent):void
         {
             if (installComponentsList.selectedItem != null)
             {
                 installComponentsList.selectedItem.selected = (event.item.selected);
                 installComponentsList.selectedItem.answered = true;
             }
             else
             {
                 for (var i:int = 0; i < _installerComponentsDataProvider.length; i++)
                 {
                     _installerComponentsDataProvider.getItemAt(i).selected = event.item.selected;
                     _installerComponentsDataProvider.getItemAt(i).answered = true;
                 }
             }
             checkIfAllRequiredComponentsPromptsAnswered();
         }

         protected function checkIfAllRequiredComponentsPromptsAnswered():void
         {
             var success:Boolean = true;
             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (obj.required && !obj.selected)
                 {
                     success = false;
                 }
             }
             installBtn.enabled = success;
         }

         /************************ Utility methods *****************/

         private function createFolder(path:String):File
         {
             var dir:File = new File(path);

             if (!dir.exists)
                 dir.createDirectory();

             return dir;
         }

         private function copyOrDownload(url:String, handlerFunction:Function, dest:File = null, errorFunction:Function = null, nocache:Boolean = false):void
         {
             if (url.search("http") == 0)
             {
                 download(url, handlerFunction, errorFunction, nocache);
             }
             else if (url.search("file://") == 0)
             {
                 download(url, handlerFunction, errorFunction, nocache);
             }
             else
             {
                 var source:File = new File(url);

                 try
                 {
                     source.copyTo(dest, true);
                 }
                 catch (error:Error)
                 {
                     if (errorFunction != null)
                     {
                         errorFunction.call(null);
                     }
                     log(_viewResourceConstants.ERROR_UNABLE_TO_COPY_FILE + error.errorID + " " + error.message);
                 }
             }
         }

         private function download(url:String, handlerFunction:Function, errorFunction:Function = null, nocache:Boolean = false):void
         {
             loader = new URLLoader();
             if (debugMode)
             {
                 log("downloading " + url);
                 if (usingDownloadCache)
                     log("using download cache");
                 if (nocache)
                     log("not caching this download");
             }
             if (usingDownloadCache && !nocache)
             {
                 var cacheURL:String;
                 if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
                 {
                     cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
                     if (debugMode)
                         log("mirror caching.  url = " + cacheURL);
                 }
                 else
                 {
                     if (url.indexOf("http") == 0)
                     {
                         var c:int = url.indexOf("/");
                         c = url.indexOf("/", c + 1);
                         c = url.indexOf("/", c + 1);
                         // that should find the slash after the server.
                         cacheURL = url.substr(c + 1);
                         if (debugMode)
                             log("http caching.  url = " + cacheURL);
                     }
                 }
                 if (cacheURL)
                 {
                     var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                     cacheFile = cacheFile.resolvePath(escape(cacheURL));
                     if (debugMode)
                         log("searching cache for " + cacheFile.url);
                     if (cacheFile.exists)
                     {
                         log(_viewResourceConstants.INFO_USING_CACHED_FILE + " " + cacheFile.url);
                         url = cacheFile.url;
                     }
                 }
             }
             var req:URLRequest = new URLRequest(url);
             //Wait for 5 minutes before aborting download attempt.  Adobe download sites as well as some Apache mirrors are extremely slow.
             req.idleTimeout = 300000;

             loader.dataFormat = URLLoaderDataFormat.BINARY;
             if (usingDownloadCache)
                 loader.addEventListener(Event.COMPLETE, function (event:Event):void
                 {
                     if (debugMode)
                         log("download complete preparing to cache");
                     var cacheURL:String;
                     if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
                     {
                         cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
                         if (debugMode)
                             log("mirror caching.  url = " + cacheURL);
                     }
                     else
                     {
                         if (url.indexOf("http") == 0)
                         {
                             var c:int = url.indexOf("/");
                             c = url.indexOf("/", c + 1);
                             c = url.indexOf("/", c + 1);
                             // that should find the slash after the server.
                             cacheURL = url.substr(c + 1);
                             if (debugMode)
                                 log("http caching.  url = " + cacheURL);
                         }
                     }
                     if (cacheURL && !nocache)
                     {
                         var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                         cacheFile = cacheFile.resolvePath(escape(cacheURL));
                         if (debugMode)
                             log("caching " + cacheFile.url);
                         if (!cacheFile.exists)
                         {
                             var fs:FileStream = new FileStream();
                             fs.open(cacheFile, FileMode.WRITE);
                             var srcData:ByteArray = ByteArray(loader.data);
                             srcData.position = 0;
                             var ba:ByteArray = new ByteArray();
                             srcData.readBytes(ba, 0, srcData.length);
                             ba.position = 0;
                             fs.writeBytes(ba, 0, ba.length);
                             fs.close();
                         }
                         else
                         {
                             if (debugMode)
                                 log("file was already in cache");
                         }
                     }

                 });
             loader.addEventListener(Event.COMPLETE, handlerFunction, false, 0, true);
             loader.addEventListener(Event.COMPLETE, handleDownloadComplete, false, 0, true);

             progressBar.percent = 0;

             if (errorFunction != null)
             {
                 loader.addEventListener(ErrorEvent.ERROR, errorFunction, false, 0, true);
                 loader.addEventListener(IOErrorEvent.IO_ERROR, errorFunction, false, 0, true);
             }
             loader.addEventListener(ProgressEvent.PROGRESS, handleDownloadProgress, false, 0, true);

             loader.load(req);
         }

         private function handleDownloadProgress(event:ProgressEvent):void
         {
             var bytesTotal:int = event.bytesTotal;
             var bytesLoaded:int = event.bytesLoaded;
             if (event.bytesTotal > 0)
             {
                 var percentLoaded:int = Math.round(bytesLoaded * 100 / bytesTotal);
                 if (logProgressEvents)
                     log("download progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);

                 progressBar.percent = percentLoaded;
             }
         }

         private function handleDownloadComplete(event:Event):void
         {
             _previousDisplayedPercent = 0;
             clearData(URLLoader(event.target));
         }

         private function clearData(v:URLLoader):void
         {
             ByteArray(v.data).clear();
             System.gc();
         }

         private function unzip(fileToUnzip:File, unzipCompleteFunction:Function, unzipErrorFunction:Function = null):void
         {
             var zipFileBytes:ByteArray = new ByteArray();
             var fs:FileStream = new FileStream();
             var fzip:Zip = new Zip();

             fs.open(fileToUnzip, FileMode.READ);
             fs.readBytes(zipFileBytes);
             fs.close();

             fzip.addEventListener(ZipEvent.FILE_LOADED, onFileLoaded, false, 0, true);
             fzip.addEventListener(Event.COMPLETE, unzipCompleteFunction, false, 0, true);
             fzip.addEventListener(Event.COMPLETE, onUnzipComplete, false, 0, true);
             if (unzipErrorFunction != null)
             {
                 fzip.addEventListener(ErrorEvent.ERROR, unzipErrorFunction, false, 0, true);
                 _fileUnzipErrorFunction = unzipErrorFunction
             }
             fzip.loadBytes(zipFileBytes);
         }

         private function onFileLoaded(e:ZipEvent):void
         {
             try
             {
                 var fzf:ZipFile = e.file;
                 var f:File;
                 if (overlaying)
                     f = _flexTempDir.resolvePath(fzf.filename);
                 else
                     f = _flexHomeDir.resolvePath(fzf.filename);
                 var fs:FileStream = new FileStream();

                 if (isDirectory(fzf))
                 {
                     // Is a directory, not a file. Dont try to write anything into it.
                     return;
                 }

                 fs.open(f, FileMode.WRITE);
                 fs.writeBytes(fzf.content);
                 fs.close();

             }
             catch (error:Error)
             {
                 _fileUnzipErrorFunction.call();
             }
         }

         private function isDirectory(f:ZipFile):Boolean
         {
             if (f.filename.substr(f.filename.length - 1) == "/" || f.filename.substr(f.filename.length - 1) == "\\")
             {
                 return true;
             }
             return false;
         }

         private function onUnzipComplete(event:Event):void
         {
             var fzip:Zip = event.target as Zip;
             fzip.close();
             fzip.removeEventListener(ZipEvent.FILE_LOADED, onFileLoaded);
             fzip.removeEventListener(Event.COMPLETE, onUnzipComplete);
         }

         private function untar(source:File, destination:File, unTarCompleteFunction:Function, unTarErrorFunction:Function):void
         {
             var tar:File;
             var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
             var arguments:Vector.<String> = new Vector.<String>();

             if (_os.isLinux())
             {
                 tar = new File("/bin/tar");
             }
             else
             {
                 tar = new File("/usr/bin/tar");
             }

             arguments.push("xf");
             arguments.push(source.nativePath);
             arguments.push("-C");
             arguments.push(destination.nativePath);

             startupInfo.executable = tar;
             startupInfo.arguments = arguments;

             _process = new NativeProcess();
             _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, unTarFileProgress, false, 0, true);
             _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarErrorFunction, false, 0, true);
             _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarError, false, 0, true);
             _process.addEventListener(NativeProcessExitEvent.EXIT, unTarCompleteFunction, false, 0, true);
             _process.addEventListener(NativeProcessExitEvent.EXIT, unTarComplete, false, 0, true);
             _process.start(startupInfo);
         }

         private function unTarError(event:Event):void
         {
             var output:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);

             log(_viewResourceConstants.ERROR_NATIVE_PROCESS_ERROR);
             log(output);
         }

         private function unTarFileProgress(event:Event):void
         {
             var output:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);

             log(output);
         }

         private function unTarComplete(event:NativeProcessExitEvent):void
         {
             _process.closeInput();
             _process.exit(true);
         }

         private function writeFileToDirectory(file:File, data:ByteArray):void
         {
             var fs:FileStream = new FileStream();
             fs.open(file, FileMode.WRITE);
             fs.writeBytes(data);
             fs.close();
         }

         private function isValidConfigFile(file:File):Boolean
         {
             var name:String = file.name;

             if (name.search("-config.xml") == -1)
             {
                 return false;
             }
             else
             {
                 return true;
             }
         }

         private function isAirConfigFile(file:File):Boolean
         {
             var name:String = file.name;

             if (name.search("air") == 0)
             {
                 return true;
             }
             else
             {
                 return false;
             }
         }

         private function log(text:String, position:int = -1, isPublic:Boolean = true, skipLog:Boolean = false):void
         {
             if (text == null)
                 text = "";
             if (position == -1)
             {
                 if (!skipLog)
                     _messages.addItem(text);
                 if (isPublic)
                     lastPublicMessage = text;
             }
             else
             {
                 _messages.addItemAt(text, position);
             }
             if (debugMode)
                 trace(text);
             if (logFile)
             {
                 var f:File = new File(logFile);
                 var fs:FileStream = new FileStream();
                 fs.open(f, FileMode.APPEND);
                 fs.writeUTFBytes(text + "\n");
                 fs.close();
             }
         }

         private var console:ConsoleWindow;

         private function showConsole(event:Event):void
         {
             if (!console || console.closed)
                 console = new ConsoleWindow();
             else if (console)
                 console.orderToFront();

             console.messages = _messages;
             console.open();
             console.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - console.nativeWindow.width / 2;
             console.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - console.nativeWindow.height / 2;
         }

         private function showMPLLicense(event:Event):void
         {
             var licenseWindow:MPLLicense = new MPLLicense();
             licenseWindow.open();
             licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
             licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
         }

         private function showAdobeLicense(event:Event):void
         {
             var licenseWindow:AdobeLicense = new AdobeLicense();
             licenseWindow.open();
             licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
             licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
         }

         private function openApacheFlexFolder(event:Event):void
         {
             _flexHomeDir.openWithDefaultApplication();
         }

         private function closeApplication(event:Event):void
         {
             removeEventListener(Event.CLOSING, closeApplication);

             if (currentState == "installState")
             {
                 if (currentStep < stepLabels.length)
                 {
                     // User aborted the installation by closing the installer
                     var activeStep:StepItem = getActiveStepItem();
                     if (_viewResourceConstants)
                         abortInstallation(_viewResourceConstants.INFO_USER_ABORT_INSTALLATION + activeStep.label);
                 }
             }

             // TODO only enable close button when finished or when an error occurs
             // TODO anything we need to clean up?
             if (console && !console.closed)
                 console.closeWindow(null);
             cleanup();
             close();
         }

         protected function getActiveStepItem():StepItem
         {
             for each (var s:StepItem in _installationSteps)
             {
                 if (s.status == StepItem.ACTIVE)
                 {
                     return s;
                 }
             }
             return null;
         }

         protected function clickLogo(event:MouseEvent):void
         {
             navigateToURL(new URLRequest(Constants.APACHE_FLEX_URL));
         }

         protected function getStepItemFromStepLabel(stepLabel:String):StepItem
         {
             for each (var s:StepItem in _installationSteps)
             {
                 if (s.label == stepLabel)
                 {
                     return s;
                 }
             }

             return null;
         }

         protected function getInstallerComponentFromLabel(key:String):InstallerComponentVO
         {
             for each (var s:InstallerComponentVO in _installerComponentsDataProvider)
             {
                 if (s.key == key)
                 {
                     return s;
                 }
             }

             return null;
         }

         protected function updateActivityStep(stepLabel:String, status:String):void
         {
             var step:StepItem = getStepItemFromStepLabel(stepLabel);

             if (step)
             {
                 step.status = status;
             }
         }

         private function isDirectoryEmpty(dir:File):Boolean
         {
             var result:Boolean;

             var filesArray:Array = dir.getDirectoryListing();

             var length:int = filesArray.length;
             result = length == 0;
             if (length == 1)
             {
                 var explodedPath:Array = File(filesArray[0]).url.split("/");

                 // the .DS_Store file doesn't bother anybody, so we can safely ignore it.
                 // also ignore local.properties so you an override install settings
                 result = explodedPath[explodedPath.length - 1] == ".DS_Store" ||
                 explodedPath[explodedPath.length - 1] == "local.properties";
             }

             return result;
         }

         protected function showDisclaimer():void
         {
             var request:URLRequest = new URLRequest(Constants.APACHE_FLEX_URL + Constants.DISCLAIMER_PATH);

             navigateToURL(request, "_blank");
         }

         protected function installComponentsList_creationCompleteHandler(event:FlexEvent):void
         {
             installComponentsList.addEventListener(InstallItemSelectionEvent.INSTALL_ITEM_SELECTION_CHANGED, handleInstallPermissionChange);
         }

         private function onMouseRoll(event:MouseEvent):void
         {
             if (event.type == MouseEvent.MOUSE_OVER)
             {
                 event.target.styleName = "linkTextHover";
             }
             else
             {
                 event.target.styleName = "linkText";
             }
         }

         private function getFlexVersionBuildString():String
         {
             var flexPropertiesFile:File = _flexHomeDir.resolvePath("flex-sdk-description.xml");
             var fs:FileStream = new FileStream();
             fs.open(flexPropertiesFile, FileMode.READ);
             var contents:XML = new XML(fs.readMultiByte(fs.bytesAvailable, "utf-8"));
             fs.close();
             return contents.version + "." + contents.build;
         }
         ]]></fx:Script>
    
    <fx:Declarations>
        <s:Sine id="ease"/>
        <s:BlurFilter id="blur"/>
    </fx:Declarations>
    
    <s:states>
        <s:State name="default"/>
        <s:State name="directoryState"/>
        <s:State name="optionsState"/>
        <s:State name="installState"/>
    </s:states>
    
    <s:transitions>
        <s:Transition id="showDefault" fromState="*" toState="default">
            <s:Sequence id="t0" targets="{[zeroStepGroup]}" effectEnd="placeGroup(zeroStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{zeroStepGroup}" xFrom="800" xTo="{this.width/2 - zeroStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showDirectory" fromState="*" toState="directoryState">
            <s:Sequence id="t1" targets="{[firstStepGroup]}" effectEnd="placeGroup(firstStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{firstStepGroup}" xFrom="800" xTo="{this.width/2 - firstStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showOptions" fromState="*" toState="optionsState">
            <s:Sequence id="t2" targets="{[secondStepGroup]}" effectEnd="placeGroup(secondStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{secondStepGroup}" xFrom="800" xTo="{this.width/2 - secondStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showInstall" fromState="*" toState="installState">
            <s:Sequence id="t3" targets="{[thirdStepGroup]}" effectEnd="placeGroup(thirdStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="true"/>
                <s:Move target="{thirdStepGroup}" xFrom="800" xTo="{this.width/2 - thirdStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="backToDefault" fromState="directoryState" toState="default">
            <s:Sequence id="t4" targets="{[zeroStepGroup]}" effectEnd="placeGroup(zeroStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{zeroStepGroup}" xFrom="-800" xTo="{this.width/2 - zeroStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="backToDirectory" fromState="optionsState" toState="directoryState">
            <s:Sequence id="t5" targets="{[firstStepGroup]}" effectEnd="placeGroup(firstStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{firstStepGroup}" xFrom="-800" xTo="{this.width/2 - firstStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
    </s:transitions>
    <s:layout>
        <s:BasicLayout/>
    </s:layout>
    <s:HGroup
        left="0"
        right="0"
        paddingLeft="20"
        paddingRight="20"
        paddingTop="5"
        horizontalAlign="right">
        <controls2:LinkButton
            text="{_viewResourceConstants.BTN_DISCLAIMER}"
            fontFamily="openSansSemibold"
            click="{showDisclaimer()}"
            />
        <s:Spacer width="100%"/>
        <s:Label id="langLabel"
                 horizontalCenter="0"
                 height="100%"
                 textAlign="right"
                 text="{_viewResourceConstants.INFO_CURRENT_LANGUAGE}"
                 fontFamily="openSansSemibold"
                 verticalAlign="middle"/>
        <s:DropDownList id="_langSelect"
                        enabled="false"
                        fontFamily="openSansSemibold"
                        change="_langSelect_changeHandler(event)">
            <s:layout>
                <s:VerticalLayout requestedRowCount="-1"/>
            </s:layout>
        </s:DropDownList>
    </s:HGroup>

    <s:HGroup verticalAlign="middle" gap="5" horizontalCenter="0" top="300">
        <s:Label text="{_viewResourceConstants.INFO_VERSION}" fontFamily="openSansBold" color="0x677084" fontSize="24" />
        <s:Label text="{APACHE_FLEX_BIN_DISTRO_VERSION}" right="0"
                 fontFamily="openSansBold"
                 color="0x172647" fontSize="70"
                 />
    </s:HGroup>
    <!--    </s:Group>-->
    <s:Panel id="zeroStepGroup"
             title="{_viewResourceConstants.INFO_SELECT_AIR_FLASH_PLAYER}"
             width="640"
             height="200"
             top="380"
             x="{zeroStepGroup.x = this.width/2 - zeroStepGroup.width/2}"
             backgroundAlpha="0">
        <s:layout>
            <s:VerticalLayout
                verticalAlign="middle"
                horizontalAlign="center"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_FLEX}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="flexVersion"
                            dataProvider="{FLEX_VERSIONS}"
                            labelField="label"
                            width="200"
                            fontFamily="openSansSemibold"
                            change="handleFlexVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_AIR}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="airVersion"
                            dataProvider="{AIR_VERSIONS}"
                            width="200"
                            fontFamily="openSansSemibold"
                            change="handleAirVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_FLASH}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="flashPlayerVersion"
                            width="200"
                            dataProvider="{FLASH_PLAYER_VERSIONS}"
                            fontFamily="openSansSemibold"
                            change="handleFlashPlayerVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:controlBarContent>
            <s:Spacer
                width="100%"/>
            <s:Button id="directoryBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_NEXT}"
                      enabled="false"
                      click="handleZeroStepNextBtnClick(event)"/>
        </s:controlBarContent>
    </s:Panel>
    
    <s:Panel id="firstStepGroup"
             title="{_viewResourceConstants.INFO_SELECT_DIRECTORY_INSTALL}"
             width="640"
             height="200"
             top="380"
             x="{firstStepGroup.x = this.width/2 - firstStepGroup.width/2}"
             visible="false"
             visible.directoryState="true"
             backgroundAlpha="0">
        <s:layout>
            <s:HorizontalLayout
                verticalAlign="middle"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:TextInput id="flexSDKTxtInput"
                     width="100%"
                     prompt="{_viewResourceConstants.SELECT_PATH_PROMPT}"
                     change="handleFlexSDXTxtInputChange(event)"/>
        <s:Button id="browseBtn"
                  styleName="browseBtnStyle"
                  width="{_standardButtonWidth}"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_BROWSE}"
                  click="browseForSDK(event)"
                  toolTip="{_viewResourceConstants.INFO_SELECT_DIRECTORY}"/>
        <s:controlBarContent>
            <s:Button id="firstStepBackBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      left="10"
                      label="{_viewResourceConstants.BTN_LABEL_BACK}"
                      enabled="true"
                      click="handleFirstStepBackBtnClick(event)"/>
            <s:Spacer
                width="100%"/>
            <s:Button id="nextBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_NEXT}"
                      enabled="false"
                      click="handleFirstStepNextBtnClick(event)"/>
        </s:controlBarContent>
    </s:Panel>
    <s:Panel id="secondStepGroup"
             title="{_viewResourceConstants.INFO_LICENSE_AGREEMENTS}"
             width="720"
             height="250"
             top="370"
             visible="false"
             visible.optionsState="true"
             backgroundAlpha="0"> 
        <s:controlBarContent>
            <s:Button id="secondStepBackBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      left="10"
                      label="{_viewResourceConstants.BTN_LABEL_BACK}"
                      enabled="true"
                      click="handleSecondStepBackBtnClick(event)"/>
            <s:Spacer
                width="100%"/>
            <s:Button id="installBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_INSTALL}"
                      enabled="false"
                      click="handleInstallBtnClick(event)"/>
        </s:controlBarContent>
        <s:layout>
            <s:VerticalLayout
                verticalAlign="middle"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:HGroup
            width="100%"
            height="100%"
            horizontalAlign="center">
            <s:List id="installComponentsList"
                    width="50%"
                    height="100%"
                    horizontalScrollPolicy="off"
                    itemRenderer="org.apache.flex.packageflexsdk.view.itemrenderers.OptionalInstallItemRenderer"
                    dataProvider="{_installerComponentsDataProvider}"
                    change="handleOptionalInstallsChange(event)" creationComplete="installComponentsList_creationCompleteHandler(event)">
                <s:layout>
                    <s:VerticalLayout/>
                </s:layout>
            </s:List>
            <s:VGroup width="50%"
                      height="100%"
                      horizontalAlign="center"
                      gap="5">
                <controls2:LinkButton id="licenseLinkBtn"
                                      text="{_currentLicenseLabel}"
                                      fontWeight="bold"
                                      click="{handleLicenceBtnClick(event)}"
                                      paddingTop="5"
                                      includeInLayout="false"
                                      />
                <s:TextArea id="optionalInstallsTxtArea" text="{_viewResourceConstants.INFO_NEED_TO_READ_AND_AGREE_TO_LICENSE}"
                            fontFamily="openSansSemiBold"
                            fontSize="12"
                            width="100%"
                            height="100%"
                            verticalScrollPolicy="off"
                            editable="false"/>
            </s:VGroup>
        </s:HGroup>
    </s:Panel>
    <s:Panel id="thirdStepGroup"
             title="{_viewResourceConstants.INFO_INSTALLING}"
             width="640"
             height="200"
             top="380"
             visible="false"
             visible.installState="true"
             backgroundAlpha="0">
        <s:layout>
            <s:VerticalLayout
                horizontalAlign="center"
                verticalAlign="middle"
                paddingTop="10"
                paddingRight="10"
                paddingLeft="10"
                gap="15"/>
        </s:layout>
        <controls1:MultiStepProgressIndicator
            steps="{_installationSteps}"/>
        <s:Label id="lastMessage"
                 text="{lastFilteredPublicMessage}"
                 fontFamily="openSansLightItalic"
                 textAlign="center"
                 width="80%" height="100%"
                 horizontalCenter="0"/>
        <controls:ProgressBar id="progressBar"
                              width="60%"
                              height="21"/>
        <s:Button id="openApacheFlexFolderBtn"
                  styleName="mainBtnStyle"
                  width="225"
                  height="32"
                  visible="false"
                  includeInLayout="false"
                  label="{_viewResourceConstants.BTN_LABEL_OPEN_APACHE_FLEX_FOLDER}"
                  toolTip="{_flexHome}"
                  click="openApacheFlexFolder(event)"/>
        <components:Tracker id="tracker" width="1" height="1" visible="false"/>
    </s:Panel>
    <s:HGroup
        left="0"
        right="0"
        bottom="20"
        paddingLeft="20"
        paddingRight="20"
        paddingTop="0"
        verticalAlign="middle">
        <s:Button id="installLogBtn"
                  styleName="genericBtnStyle"
                  width="110"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_INSTALL_LOG}"
                  click="showConsole(event)"/>
        <s:Spacer width="100%"/>
        <s:Label fontFamily="openSansLightItalic" text="{_viewResourceConstants.INFO_TRACKING}"
                 styleName="linkText" maxDisplayedLines="2"
                 mouseOver="onMouseRoll(event)" mouseOut="onMouseRoll(event)"
                 click="navigateToURL(new URLRequest('http://flex.apache.org/about-privacy.html'))"
                 buttonMode="true"
                 useHandCursor="true"
                 mouseChildren="false"/>
        <s:Spacer width="100%"/>
        <s:Button id="closeBtn"
                  styleName="genericBtnStyle"
                  width="{_standardButtonWidth}"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_CLOSE}"
                  click="closeApplication(event)"/>
    </s:HGroup>
    <!-- used to measure text -->
    <s:Button id="hiddenButton" visible="false" includeInLayout="false"/>
</s:WindowedApplication>
