<?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.packageflexsdk.util.ApacheURLLoader;

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

        // This force-links all of the ant task handlers into the Installer.
        // The Installer doesn't use most of them directly but some script
        // it runs might.
        import AntClasses;

        AntClasses;

        import org.apache.flex.ant.Ant;
        import org.apache.flex.ant.tags.Checksum;
        import org.apache.flex.ant.tags.Copy;
        import org.apache.flex.ant.tags.Get;
        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 org.osmf.utils.OSMFStrings;

        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;
        private var newSDKSelected:Boolean = true;

        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:ApacheURLLoader;

        /**
         * 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:ApacheURLLoader;
        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 compList:XMLList;
        private var stepIDs:Vector.<String> = new Vector.<String>();
        private var stepLabels:Vector.<String> = new Vector.<String>();
        private var currentStep:int = 0;

        private var lastLicenseItemSelected:int = 0;

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

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

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

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

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

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

        [Bindable]
        private var _standardButtonWidth:Number = 88;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            if (languageOverride)
            {
                userLocale = languageOverride;
            }

            loadDefaultLanguage(userLocale);
        }

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

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

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

            if (userLocale == "en_US")
            {
                var ba:ByteArray = new en_US_Properties() as ByteArray;
                var data:String = ba.readUTFBytes(ba.bytesAvailable);
                installLanguage(userLocale, data);
                completeFunction();
                return;
            }
            var n:int = supportedLanguages.length;
            for (var i:int = 0; i < n; i++)
            {
                if (supportedLanguages[i].data == userLocale)
                {
                    languageID = userLocale;
                    languageURL = supportedLanguages[i].path;
                    var url:URLRequest = new URLRequest(languageURL);
                    loader = new ApacheURLLoader();
                    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);
                //request = new URLRequest(Constants.CONFIG_XML_NAME);
            }

            _loader = new ApacheURLLoader();

            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(HTTPStatusEvent.HTTP_RESPONSE_STATUS, xmlLoadStatus, false, 0, true);
            _loader.addEventListener(IOErrorEvent.IO_ERROR, xmlError, false, 0, true);
            _loader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);
        }

        protected function xmlLoadStatus(event:HTTPStatusEvent):void
        {
            if (event.status >= 400)
            {
                log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
                log("\tServer Status: " + event.status);
            }
        }

        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;
            }

            newSDKSelected = 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)
            {
                if (newSDKSelected)
                {
                    var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
                    loader = new ApacheURLLoader();
                    loader.dataFormat = URLLoaderDataFormat.TEXT;
                    loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
                    loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
                    loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallerXMLError);

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

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

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

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

            showOptionsState();
        }

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

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

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

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

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

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

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

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

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

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

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

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

        protected function initializeInstallerComponentsDataProvider():void
        {
            var versionNum:int = int(APACHE_FLEX_BIN_DISTRO_VERSION.split('.').join(''));
            _installerComponentsDataProvider = new ArrayCollection();
            /**
             * version 4.13.0 of the SDK is when the installer started using the new xml based
             * way of displaying/updating required or optional components of the installer
             */
            if (usingXML && (versionNum >= 4130))
            {
                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);
                }
            }
            else
            {
                _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_BLAZEDS,
                        _viewResourceConstants.ASK_BLAZEDS,
                        _viewResourceConstants.LICENSE_BLAZEDS,
                        _viewResourceConstants.LICENSE_URL_BLAZEDS,
                        "STEP_OPTIONAL_INSTALL_BLAZEDS", false));
                _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_REQUIRED_INSTALL_OFL_FONTS,
//                      _viewResourceConstants.ASK_OFL_FONTS,
//                      _viewResourceConstants.LICENSE_OFL_FONTS,
//                      _viewResourceConstants.LICENSE_URL_OFL_FONTS,
//                      "STEP_REQUIRED_INSTALL_OFL_FONTS", true));
            }
        }

        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
        {
            /*APACHE_FLEX_BIN_DISTRO_VERSION =  flexVersion.selectedItem.version;
             APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = flexVersion.selectedItem.label;*/
            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.validMD5)
            {
                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);
                }
            }
            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(ApacheURLLoader(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(ApacheURLLoader(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(ApacheURLLoader(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(ApacheURLLoader(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(ApacheURLLoader(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 ApacheURLLoader();
            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(ApacheURLLoader(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();

                // This makes sure to update the Title of the license being displayed if the user changes languages
                _currentLicenseLabel = _installerComponentsDataProvider.getItemAt(lastLicenseItemSelected).licenseName;

            }
        }

        private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;

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

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

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

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

            // Store the current selected item in order to have the license title update if the language is changed
            lastLicenseItemSelected = installComponentsList.selectedIndex;

            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 ApacheURLLoader();
            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(ApacheURLLoader(event.target));
        }

        private function clearData(v:ApacheURLLoader):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
        {
            // try forcing GC before each step
            try {
                var lc1:LocalConnection = new LocalConnection();
                var lc2:LocalConnection = new LocalConnection();
                
                lc1.connect("name");
                lc2.connect("name");
            }
            catch (error:Error)
            {
            }
            
            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:Group width="100%" top="275">-->
    <!--        <s:HGroup gap="0" horizontalCenter="0" top="30">
    <s:Label text="apache" fontFamily="openSansBold" color="0x677084" fontSize="24" />
    <s:Label text="Flex" right="0"
    fontFamily="openSansBold"
    color="0x172647" fontSize="70"
    />
    </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"
                      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"
                      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:HGroup
        width="100%"
        height="20"
        horizontalAlign="center"
        verticalAlign="middle">
        <s:CheckBox id="installChkBx"
        label="{_viewResourceConstants.INSTALL_AGREE_ALL}"
        selected="false" 
        visible="true"/>
        </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>
