<?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();
             }

             else
             {
                 log("Internet connection unavailable");
                 abortInstallation("Internet connection unavailable.");
             }
             logVersion();
         }

         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, handleInstallIOXMLError);

                 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;
             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 handleInstallIOXMLError(event:IOErrorEvent):void
         {
             // Stream Error 2032 here means that the SSL connection can't be created.  TLS/SSL error?
             log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL + " with  " + event.text);
             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;
             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>
