List:Commits« Previous MessageNext Message »
From:Mike Lischke Date:March 18 2011 10:29am
Subject:bzr commit into wex-installer-1.0 branch (mike.lischke:371)
View as plain text  
#At file:///D:/Work/MySQL/installer/ based on revid:iggy@mysql.com-20110317155158-t79o9hyfs6e2afuz

  371 Mike Lischke	2011-03-18
      - ManifestUpdater: improved file matching to account for different architectures.
      - Setup: added 64 bit msi files for server and connectors.
      - Setup: set default package to 5.5 64 bit. This will automatically adjusted for 32 bit platforms.
      - Setup: added 64 bit product catalogs and products.
      - FeatureBox: reworked drawing.
      - FeatureBox: added central product retrieval function based on architecture, active catalog, all/installed inclusion.
      - FeatureTree: reworked drawing.
      - FeatureBox + FeatureTree: show architecture in titles if Any is currently selected. (In debug mode the architecture is always displayed).
      - Features: added support for architecture choice.
      - Changed logic for ActiveCatalog: the catalog is now persistently stored, is usually always assigned except if all/installed items are selected in the custom setup and is set to the default catalog if the user switchs to any preset setup.
      - RemoveComplete: improved directory removal. Care is taken to remove any read-only setting bevor deletion.
      - Moved handling for the default catalog from Program.cs to the ProductManager.
      - Added support for OS architecture detection.
      - Some minor refactorings and additional log output.

    added:
      WexInstaller/Controls/FeatureTreeView.resx
    modified:
      ManifestUpdater/Program.cs
      Setup/IncludeMSIs.wxs
      Setup/Setup_Net.wixproj
      Setup/manifest-base.xml
      StandardPlugins/Server/ServerConfigPanel2.cs
      WexInstaller.Core/InstallerConfiguration.cs
      WexInstaller.Core/Package.cs
      WexInstaller.Core/Product.cs
      WexInstaller.Core/ProductCatalog.cs
      WexInstaller.Core/ProductFeature.cs
      WexInstaller.Core/ProductManager.cs
      WexInstaller.Core/WexInstaller.Core.csproj
      WexInstaller.Core/Win32.cs
      WexInstaller/Controls/FeatureBox.cs
      WexInstaller/Controls/FeatureTreeView.cs
      WexInstaller/InstallWizard/Features.Designer.cs
      WexInstaller/InstallWizard/Features.cs
      WexInstaller/InstallWizard/Features.resx
      WexInstaller/InstallWizard/InstallType.cs
      WexInstaller/Program.cs
      WexInstaller/RemovePanels/RemoveComplete.cs
      WexInstaller/WexInstaller.csproj
      installer-vs2010.sln
=== modified file 'ManifestUpdater/Program.cs'
=== modified file 'ManifestUpdater/Program.cs'
--- a/ManifestUpdater/Program.cs	2011-03-02 15:58:16 +0000
+++ b/ManifestUpdater/Program.cs	2011-03-18 10:29:04 +0000
@@ -1,214 +1,234 @@
 using System;
 using System.Collections.Generic;
-using System.Text;
+using System.IO;
+using Microsoft.Tools.WindowsInstallerXml.Msi;
+using System.Text.RegularExpressions;
+
 using Mono.Options;
+
 using WexInstaller.Core;
-using System.IO;
-using Microsoft.Tools.WindowsInstallerXml.Msi;
 
 namespace ManifestUpdater
 {
-    class Program
-    {
-        static string inFile = null;
-        static string outFile = null;
-        static string cacheDir = null;
-        static bool wait = true;
-
-        static void Main(string[] args)
-        {
-
-            // Parse our command line args
-            OptionSet p = new OptionSet()
-              .Add("input=|in=", input => inFile=input)
-              .Add("output=|out=", output => outFile=output)
-              .Add("cachedir=|cache=", dir => cacheDir=dir)
-              .Add("wait=", dowait => wait = (dowait == "y" || dowait == "Y"));
-            p.Parse(args);
-
-            // load the manifest
-            ProductManifest manifest = ProductManifest.Load(inFile);
-
-            foreach (ProductCategory category in manifest.ProductCategories)
-            {
-                foreach (Product product in category.Products)
-                {
-                    if (product.Packages.Count != 1) continue;
-                    Package package = product.Packages[0];
-                    UpdateProductAndPackage(product, package);
-                }
-            }
-
-            // now save the manifest
-            manifest.Save(outFile);
-            if (wait)
-            {
-                Console.WriteLine();
-                Console.WriteLine("Manifest generation done.  Press Enter.");
-                Console.ReadLine();
-            }
-        }
-
-        static void UpdateProductAndPackage(Product product, Package package)
-        {
-            // first find the latest MSI in our cache
-            string msiFile = FindLatestVersion(package.FileName);
-            if (String.IsNullOrEmpty(msiFile)) return;
-
-            UpdateProductInfo(product, msiFile);
-            UpdatePackageInfo(package, msiFile);
-        }
-
-        static string FindLatestVersion(string fileName)
-        {
-            int index = fileName.IndexOf('.');
-            index = fileName.IndexOf('.', index + 1);
-            string baseName = fileName.Substring(0, index);
-
-            Version newestVersion = new Version(0, 0);
-            string newestFile = null;
-
-            string[] files = Directory.GetFiles(cacheDir, baseName + "*.msi");
-            foreach (string file in files)
-            {
-                Version v = new Version(GetProperty(file, "ProductVersion"));
-                if (v <= newestVersion) continue;
-                newestVersion = v;
-                newestFile = file;
-            }
-            return newestFile;
-        }
-
-        static void UpdateProductInfo(Product product, string msiFile)
-        {
-            product.UpgradeId = GetProperty(msiFile, "UpgradeCode");
-            if (String.IsNullOrEmpty(product.UpgradeId))
-                Console.WriteLine(String.Format("Warning: {0} doesn't have an upgrade code",
-                    Path.GetFileName(msiFile)));
-        }
-
-        static void UpdatePackageInfo(Package package, string msiFile)
-        {
-            package.FileName = Path.GetFileName(msiFile);
-            package.ThisVersion = GetProperty(msiFile, "ProductVersion");
-            package.Id = GetProperty(msiFile, "ProductCode");
-            package.Features.Clear();
-            SetFeatures(msiFile, package);
-        }
-
-        static void SetFeatures(string msiFile, Package package)
-        {
-            Database msiDb = new Database(msiFile, OpenDatabase.ReadOnly);
-            GetFeatures(msiDb, package);
-            msiDb.Close();
-        }
-
-        static void GetFeatures(Database msiDb, object parent)
-        {
-            List<ProductFeature> features = new List<ProductFeature>();
-
-            if (parent is Package)
-                (parent as Package).Features = features;
-            else
-                (parent as ProductFeature).Features = features;
-            string parentName = parent is Package ? null : (parent as ProductFeature).Name;
-
-            using (View featureView = msiDb.OpenExecuteView("SELECT * FROM Feature ORDER BY Display"))
-            {
-                Record record;
-                while (null != (record = featureView.Fetch()))
-                {
-                    int featureLevel = record.GetInteger(6);
-                    if (featureLevel == 0) continue;    // level 0 features will not be installed anyway
-
-                    string featureParent = record.GetString(2);
-                    if (featureParent != parentName) continue;
-
-                    ProductFeature feature = new ProductFeature();
-                    feature.Name = record.GetString(1);
-                    feature.Title = record.GetString(3);
-                    feature.Description = record.GetString(4);
-                    feature.Display = record.GetInteger(5);
-                    feature.HasComponents = FeatureHasComponents(msiDb, feature.Name);
-                    feature.SizeEstimate = GetSizeEstimate(msiDb, feature.Name);
-                    features.Add(feature);
-                }
-            }
-
-            // now recurse
-            if (features != null && features.Count > 0)
-                foreach (ProductFeature feature in features)
-                    GetFeatures(msiDb, feature);
-        }
-
-        static long GetSizeEstimate(Database msiDb, string featureName)
-        {
-            List<string> components = GetComponentsForFeature(msiDb, featureName);
-
-            long size = 0;
-            foreach (string component in components)
-                size += GetSizeOfComponent(msiDb, component);
-
-            return size;
-        }
-
-        static List<string> GetComponentsForFeature(Database msiDb, string feature)
-        {
-            List<string> components = new List<string>();
-
-            using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
-            {
-                Record record;
-                while (null != (record = view.Fetch()))
-                {
-                    if (String.Compare(feature, record.GetString(1), true) == 0)
-                        components.Add(record.GetString(2));
-                }
-            }
-            return components;
-        }
-
-        static long GetSizeOfComponent(Database msiDb, string component)
-        {
-            long size = 0;
-
-            using (View view = msiDb.OpenExecuteView("SELECT * FROM File"))
-            {
-                Record record;
-                while (null != (record = view.Fetch()))
-                {
-                    if (String.Compare(component, record.GetString(2), true) == 0)
-                        size += (long)record.GetInteger(4);
-                }
-            }
-            return size;
-        }
-
-        static bool FeatureHasComponents(Database msiDb, string featureName)
-        {
-            using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
-            {
-                Record record;
-                while (null != (record = view.Fetch()))
-                {
-                    if (String.Compare(featureName, record.GetString(1), true) == 0)
-                        return true;
-                }
-            }
-            return false;
-        }
-
-        static string GetProperty(string msiFile, string property)
-        {
-            using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
-            {
-                string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'", property);
-                View view = d.OpenView(sql);
-                view.Execute();
-                Record record = view.Fetch();
-                if (record == null) return String.Empty;
-                return record.GetString(2);
-            }
-        }
-    }
+  class Program
+  {
+    static string inFile = null;
+    static string outFile = null;
+    static string cacheDir = null;
+    static bool wait = true;
+
+    static void Main(string[] args)
+    {
+      // Parse our command line args
+      OptionSet p = new OptionSet()
+        .Add("input=|in=", input => inFile=input)
+        .Add("output=|out=", output => outFile=output)
+        .Add("cachedir=|cache=", dir => cacheDir=dir)
+        .Add("wait=", dowait => wait = (dowait == "y" || dowait == "Y"));
+      p.Parse(args);
+
+      // load the manifest
+      ProductManifest manifest = ProductManifest.Load(inFile);
+
+      foreach (ProductCategory category in manifest.ProductCategories)
+      {
+        foreach (Product product in category.Products)
+        {
+          if (product.Packages.Count != 1) continue;
+          Package package = product.Packages[0];
+          UpdateProductAndPackage(product, package);
+        }
+      }
+
+      // now save the manifest
+      manifest.Save(outFile);
+      if (wait)
+      {
+        Console.WriteLine();
+        Console.WriteLine("Manifest generation done.  Press Enter.");
+        Console.ReadLine();
+      }
+    }
+
+    static void UpdateProductAndPackage(Product product, Package package)
+    {
+      // first find the latest MSI in our cache
+      string msiFile = FindLatestVersion(package.FileName);
+      if (String.IsNullOrEmpty(msiFile))
+        return;
+
+      UpdateProductInfo(product, msiFile);
+      UpdatePackageInfo(package, msiFile);
+    }
+
+    /// <summary>
+    /// Given a complete file name the function looks for similar file names, which only differ
+    /// in certain parts (mainly the embedded version number) to find the newest of these files.
+    /// </summary>
+    /// <param name="fileName">The path and file name used as patter to look for more files.</param>
+    /// <returns>The found file with the latest version or null if none could be found.</returns>
+    static string FindLatestVersion(string fileName)
+    {
+      // Names adhere to the pattern mysql-([a-zA-Z\+]+-)*[0-9]\.[0-9]\.[0-9][0-9]-win(32|x64)\.msi
+      // e.g. mysql-5.5.9-win32.msi, or mysql-connector-odbc-5.1.8-winx64.msi.
+      // Extract the architecture and extension part, which forms the end of our search pattern.
+      Regex filePattern = new Regex(@"(?<baseName>mysql-([a-zA-Z\+]+-)*\d\.\d\.)(\d)+(?<ending>-win(32|x64)\.msi)$");
+      Match match = filePattern.Match(fileName);
+      string newestFile = null;
+      if (match.Success)
+      {
+        string ending = match.Groups["ending"].Value;
+        string baseName = match.Groups["baseName"].Value;
+
+        Version newestVersion = new Version(0, 0);
+
+        string[] files = Directory.GetFiles(cacheDir, baseName + "*" + ending);
+        foreach (string file in files)
+        {
+          Version v = new Version(GetProperty(file, "ProductVersion"));
+          if (v <= newestVersion) continue;
+          newestVersion = v;
+          newestFile = file;
+        }
+      }
+      return newestFile;
+    }
+
+    static void UpdateProductInfo(Product product, string msiFile)
+    {
+      product.UpgradeId = GetProperty(msiFile, "UpgradeCode");
+      if (String.IsNullOrEmpty(product.UpgradeId))
+        Console.WriteLine(String.Format("Warning: {0} doesn't have an upgrade code",
+          Path.GetFileName(msiFile)));
+    }
+
+    static void UpdatePackageInfo(Package package, string msiFile)
+    {
+      package.FileName = Path.GetFileName(msiFile);
+      package.ThisVersion = GetProperty(msiFile, "ProductVersion");
+      package.Id = GetProperty(msiFile, "ProductCode");
+      package.Features.Clear();
+      SetFeatures(msiFile, package);
+    }
+
+    static void SetFeatures(string msiFile, Package package)
+    {
+      Database msiDb = new Database(msiFile, OpenDatabase.ReadOnly);
+      GetFeatures(msiDb, package);
+      msiDb.Close();
+    }
+
+    static void GetFeatures(Database msiDb, object parent)
+    {
+      List<ProductFeature> features = new List<ProductFeature>();
+
+      if (parent is Package)
+        (parent as Package).Features = features;
+      else
+        (parent as ProductFeature).Features = features;
+      string parentName = parent is Package ? null : (parent as ProductFeature).Name;
+
+      using (View featureView = msiDb.OpenExecuteView("SELECT * FROM Feature ORDER BY Display"))
+      {
+        Record record;
+        while (null != (record = featureView.Fetch()))
+        {
+          int featureLevel = record.GetInteger(6);
+          if (featureLevel == 0)
+            continue;    // level 0 features will not be installed anyway
+
+          string featureParent = record.GetString(2);
+          if (featureParent != parentName)
+            continue;
+
+          ProductFeature feature = new ProductFeature();
+          feature.Name = record.GetString(1);
+          feature.Title = record.GetString(3);
+          feature.Description = record.GetString(4);
+          feature.Display = record.GetInteger(5);
+          feature.HasComponents = FeatureHasComponents(msiDb, feature.Name);
+          feature.SizeEstimate = GetSizeEstimate(msiDb, feature.Name);
+          features.Add(feature);
+        }
+      }
+
+      // now recurse
+      if (features != null && features.Count > 0)
+        foreach (ProductFeature feature in features)
+          GetFeatures(msiDb, feature);
+    }
+
+    static long GetSizeEstimate(Database msiDb, string featureName)
+    {
+      List<string> components = GetComponentsForFeature(msiDb, featureName);
+
+      long size = 0;
+      foreach (string component in components)
+        size += GetSizeOfComponent(msiDb, component);
+
+      return size;
+    }
+
+    static List<string> GetComponentsForFeature(Database msiDb, string feature)
+    {
+      List<string> components = new List<string>();
+
+      using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
+      {
+        Record record;
+        while (null != (record = view.Fetch()))
+        {
+          if (String.Compare(feature, record.GetString(1), true) == 0)
+            components.Add(record.GetString(2));
+        }
+      }
+      return components;
+    }
+
+    static long GetSizeOfComponent(Database msiDb, string component)
+    {
+      long size = 0;
+
+      using (View view = msiDb.OpenExecuteView("SELECT * FROM File"))
+      {
+        Record record;
+        while (null != (record = view.Fetch()))
+        {
+          if (String.Compare(component, record.GetString(2), true) == 0)
+            size += (long)record.GetInteger(4);
+        }
+      }
+      return size;
+    }
+
+    static bool FeatureHasComponents(Database msiDb, string featureName)
+    {
+      using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
+      {
+        Record record;
+        while (null != (record = view.Fetch()))
+        {
+          if (String.Compare(featureName, record.GetString(1), true) == 0)
+            return true;
+        }
+      }
+      return false;
+    }
+
+    static string GetProperty(string msiFile, string property)
+    {
+      using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
+      {
+        string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'",
+          property);
+        View view = d.OpenView(sql);
+        view.Execute();
+        Record record = view.Fetch();
+        if (record == null)
+          return String.Empty;
+
+        return record.GetString(2);
+      }
+    }
+  }
 }

=== modified file 'Setup/IncludeMSIs.wxs'
--- a/Setup/IncludeMSIs.wxs	2011-03-14 15:50:43 +0000
+++ b/Setup/IncludeMSIs.wxs	2011-03-18 10:29:04 +0000
@@ -5,10 +5,14 @@
       <Directory Id="ProductCache" Name="Product Cache">
         <Component Id="Products" Guid="88D9D419-FCCB-4B4B-881E-FAE4D29C81B9" Permanent="yes">
           <!--File Id="server51" Name="mysql-5.1.55-win32.msi" Source="ProductCache\mysql-5.1.56-win32.msi"/ -->
-          <File Id="server55" Name="mysql-5.5.9-win32.msi" Source="ProductCache\mysql-5.5.9-win32.msi"/>
-          <File Id="connector_cpp_10" Name="mysql-connector-c++-1.1.0-win32.msi" Source="ProductCache\mysql-connector-c++-1.1.0-win32.msi"/>
-          <File Id="connector_c_60" Name="mysql-connector-c-6.0.2-win32.msi" Source="ProductCache\mysql-connector-c-6.0.2-win32.msi"/>
-          <File Id="connector_odbc_51" Name="mysql-connector-odbc-5.1.8-win32.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-win32.msi"/>
+          <File Id="server55_x86" Name="mysql-5.5.9-win32.msi" Source="ProductCache\mysql-5.5.9-win32.msi"/>
+          <File Id="server55_x64" Name="mysql-5.5.9-winx64.msi" Source="ProductCache\mysql-5.5.9-winx64.msi"/>
+          <File Id="connector_cpp_10_x86" Name="mysql-connector-c++-1.1.0-win32.msi" Source="ProductCache\mysql-connector-c++-1.1.0-win32.msi"/>
+          <File Id="connector_cpp_10_x64" Name="mysql-connector-c++-1.1.0-winx64.msi" Source="ProductCache\mysql-connector-c++-1.1.0-winx64.msi"/>
+          <File Id="connector_c_60_x86" Name="mysql-connector-c-6.0.2-win32.msi" Source="ProductCache\mysql-connector-c-6.0.2-win32.msi"/>
+          <File Id="connector_c_60_x64" Name="mysql-connector-c-6.0.2-winx64.msi" Source="ProductCache\mysql-connector-c-6.0.2-winx64.msi"/>
+          <File Id="connector_odbc_51_x86" Name="mysql-connector-odbc-5.1.8-win32.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-win32.msi"/>
+          <File Id="connector_odbc_51_x64" Name="mysql-connector-odbc-5.1.8-winx64.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-winx64.msi"/>
           <!--<File Id="examples_51" Name="mysql-examples-5.1.0.msi" Source="ProductCache\mysql-examples-5.1.0.msi"/> -->
           <File Id="examples_55" Name="mysql-examples-5.5.0.msi" Source="ProductCache\mysql-examples-5.5.0.msi"/>
           <File Id="universal_installer_document_bundle_10" Name="mysql-universal-installer-document-bundle-1.0.0.0.msi" Source="ProductCache\mysql-universal-installer-document-bundle-1.0.0.0.msi"/>

=== modified file 'Setup/Setup_Net.wixproj'
--- a/Setup/Setup_Net.wixproj	2011-03-02 22:27:21 +0000
+++ b/Setup/Setup_Net.wixproj	2011-03-18 10:29:04 +0000
@@ -6,7 +6,7 @@
     <ProductVersion>3.5</ProductVersion>
     <ProjectGuid>{fbc6c598-ec89-49e6-8fe4-4140141761cc}</ProjectGuid>
     <SchemaVersion>2.0</SchemaVersion>
-    <OutputName>mysql-universal-installer-1.0.6.0-b-net</OutputName>
+    <OutputName>mysql-universal-installer-1.0.9</OutputName>
     <OutputType>Package</OutputType>
     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
@@ -16,7 +16,7 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <OutputPath>bin\$(Configuration)\</OutputPath>
     <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
-    <DefineConstants>ProductVersion=1.0.6.0;ProductName=MySQL Universal Installer;CatalogName=mysql-5.5-gpl</DefineConstants>
+    <DefineConstants>ProductVersion=1.0.9.0;ProductName=MySQL Universal Installer;CatalogName=mysql-5.5-winx64-gpl</DefineConstants>
     <SuppressPdbOutput>True</SuppressPdbOutput>
     <VerboseOutput>True</VerboseOutput>
   </PropertyGroup>

=== modified file 'Setup/manifest-base.xml'
--- a/Setup/manifest-base.xml	2011-03-17 15:06:16 +0000
+++ b/Setup/manifest-base.xml	2011-03-18 10:29:04 +0000
@@ -4,58 +4,107 @@
   <UpdateVersion></UpdateVersion>
   <UpdateHash></UpdateHash>
   <ProductCatalogs>
-    <ProductCatalog id="mysql-5.5-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
-      <SetupTypes>
-        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
-        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
-        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
-        <SetupType flag="64" name="Full" description="Installs all products from this catalog" />
-        <SetupType flag="128" name="Custom" description="The user can select which products to install" />
-      </SetupTypes>
-      <CatalogProducts>
-        <CatalogProduct productId="mysql-server-5.5-gpl" setupTypeFlags="3" />
-        <CatalogProduct productId="workbench" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-odbc" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-c" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-cpp" setupTypeFlags="5" />
-        <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
-      </CatalogProducts>
-    </ProductCatalog>
-    <ProductCatalog id="mysql-5.1-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
-      <SetupTypes>
-        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
-        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
-        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
-        <SetupType flag="64" name="Full" description="Installs all products from this catalog" />
-        <SetupType flag="128" name="Custom" description="The user can select which products to install" />
-      </SetupTypes>
-      <CatalogProducts>
-        <CatalogProduct productId="mysql-server-5.1-gpl" setupTypeFlags="3" />
-        <CatalogProduct productId="workbench" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-odbc" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-c" setupTypeFlags="5" />
-        <CatalogProduct productId="connector-cpp" setupTypeFlags="5" />
-        <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+    <ProductCatalog id="mysql-5.5-win32-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
+      <SetupTypes>
+        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+        <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+      </SetupTypes>
+      <CatalogProducts>
+        <CatalogProduct productId="mysql-server-5.5-win32-gpl" setupTypeFlags="3" />
+        <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-odbc-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
+        <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+      </CatalogProducts>
+    </ProductCatalog>
+    <ProductCatalog id="mysql-5.5-winx64-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
+      <SetupTypes>
+        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+        <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+      </SetupTypes>
+      <CatalogProducts>
+        <CatalogProduct productId="mysql-server-5.5-winx64-gpl" setupTypeFlags="3" />
+        <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-odbc-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
+        <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+      </CatalogProducts>
+    </ProductCatalog>
+    <ProductCatalog id="mysql-5.1-win32-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
+      <SetupTypes>
+        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products." />
+        <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+        <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+      </SetupTypes>
+      <CatalogProducts>
+        <CatalogProduct productId="mysql-server-5.1-win32-gpl" setupTypeFlags="3" />
+        <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-odbc-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+        <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
+      </CatalogProducts>
+    </ProductCatalog>
+    <ProductCatalog id="mysql-5.1-winx64-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
+      <SetupTypes>
+        <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+        <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+        <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products." />
+        <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+        <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+      </SetupTypes>
+      <CatalogProducts>
+        <CatalogProduct productId="mysql-server-5.1-winx64-gpl" setupTypeFlags="3" />
+        <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-odbc-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
+        <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+        <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
       </CatalogProducts>
     </ProductCatalog>
   </ProductCatalogs>
+  
   <ProductCategories>
     <ProductCategory name="Server" title="MySql Servers" description="MySQL Database Servers">
-      <Product name="mysql-server-5.5-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-5.5.8-win32.msi" id="" thisVersion="">
-          </Package>
-        </Packages>
-      </Product>
-      <Product name="mysql-server-5.1-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
+      <Product name="mysql-server-5.5-win32-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
+        <Packages>
+          <Package type="MSI" arch="X86" filename="mysql-5.5.8-win32.msi" id="" thisVersion="" />
+        </Packages>
+      </Product>
+      <Product name="mysql-server-5.5-winx64-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
+        <Packages>
+          <Package type="MSI" arch="X64" filename="mysql-5.5.8-winx64.msi" id="" thisVersion="" />
+        </Packages>
+      </Product>
+      <Product name="mysql-server-5.1-win32-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
         <Packages>
           <Package type="MSI" arch="X86" filename="mysql-5.1.54-win32.msi" id="" thisVersion="">
           </Package>
         </Packages>
       </Product>
+      <Product name="mysql-server-5.1-winx64-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
+        <Packages>
+          <Package type="MSI" arch="X64" filename="mysql-5.1.54-winx64.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
     </ProductCategory>
     <ProductCategory name="Application" title="Applications" description="Applications that work with MySQL">
-      <Product name="workbench" title="MySQL Workbench" description="The MySQL GUI Developer tool" upgradeId="" urlBaseDir="MySQLGUITools">
+      <Product name="workbench-win32" title="MySQL Workbench" description="The MySQL GUI Developer tool" upgradeId="" urlBaseDir="MySQLGUITools">
         <Packages>
           <Package type="MSI" arch="X86" filename="mysql-workbench-gpl-5.2.31a-win32.msi" id="" thisVersion="">
           </Package>
@@ -63,41 +112,65 @@
       </Product>
     </ProductCategory>
     <ProductCategory name="Connector" title="MySQL Connectors" description="Database drivers for programming languages">
-      <Product name="connector-odbc" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-connector-odbc-5.1.6-win32.msi" id="" thisVersion="">
-          </Package>
-        </Packages>
-      </Product>
-      <Product name="connector-cpp" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-connector-c++-1.0.5-win32.msi" id="" thisVersion="">
-          </Package>
-        </Packages>
-      </Product>
-      <Product name="connector-C" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
+      <Product name="connector-odbc-win32" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
+        <Packages>
+          <Package type="MSI" arch="X86" filename="mysql-connector-odbc-5.1.8-win32.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="connector-odbc-winx64" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
+        <Packages>
+          <Package type="MSI" arch="X64" filename="mysql-connector-odbc-5.1.8-winx64.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="connector-cpp-win32" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
+        <Packages>
+          <Package type="MSI" arch="X86" filename="mysql-connector-c++-1.1.0-win32.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="connector-cpp-winx64" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
+        <Packages>
+          <Package type="MSI" arch="X64" filename="mysql-connector-c++-1.1.0-winx64.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="connector-c-win32" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
         <Packages>
           <Package type="MSI" arch="X86" filename="mysql-connector-c-6.0.2-win32.msi" id="" thisVersion="">
           </Package>
         </Packages>
       </Product>
+      <Product name="connector-c-winx64" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
+        <Packages>
+          <Package type="MSI" arch="X64" filename="mysql-connector-c-6.0.2-winx64.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
     </ProductCategory>
     <ProductCategory name="Documentation" title="Documentation" description="">
-      <Product name="Universal-Docs" title="MySQL Documentation" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-universal-installer-document-bundle-1.0.0.0.msi" id="" thisVersion="">
-          </Package>
-        </Packages>
-      </Product>
-      <Product name="examples-5.1" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-examples-5.1.0.msi" id="" thisVersion="">
-          </Package>
-        </Packages>
-      </Product>
-      <Product name="examples-5.5" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
-        <Packages>
-          <Package type="MSI" arch="X86" filename="mysql-examples-5.5.0.msi" id="" thisVersion="">
+      <Product name="mysql-documentation-5.5" title="MySQL Documentation 5.5" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+        <Packages>
+          <Package type="MSI" arch="Any" filename="mysql-documentation-5.5.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="mysql-documentation-5.1" title="MySQL Documentation 5.1" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+        <Packages>
+          <Package type="MSI" arch="Any" filename="mysql-documentation-5.1.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="examples-5.5" title="Samples and Examples 5.5" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+        <Packages>
+          <Package type="MSI" arch="Any" filename="mysql-examples-5.5.0.msi" id="" thisVersion="">
+          </Package>
+        </Packages>
+      </Product>
+      <Product name="examples-5.1" title="Samples and Examples 5.1" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+        <Packages>
+          <Package type="MSI" arch="Any" filename="mysql-examples-5.1.0.msi" id="" thisVersion="">
           </Package>
         </Packages>
       </Product>

=== modified file 'StandardPlugins/Server/ServerConfigPanel2.cs'
--- a/StandardPlugins/Server/ServerConfigPanel2.cs	2011-03-07 12:55:25 +0000
+++ b/StandardPlugins/Server/ServerConfigPanel2.cs	2011-03-18 10:29:04 +0000
@@ -65,9 +65,11 @@
       if (Controller.Template != null && Controller.Template.Reconfiguring)
       {
         enableTCPIP.Checked = Controller.Template.EnableNetworking;
+        enableTCPIP_CheckedChanged(null, null);
         if (enableTCPIP.Checked)
           portNumber.Text = Controller.Template.Port;
 
+        // TODO: check if the service actually exists (if not enable service name edit).
         if (!String.IsNullOrEmpty(Controller.ServiceName))
         {
           serviceName.Text = Controller.ServiceName;
@@ -105,9 +107,12 @@
 
     public override bool NextOk()
     {
-      if (portErrorSign.Visible) return false;
-      if (rootPwdErrorSign.Visible) return false;
-      if (serviceErrorSign.Visible) return false;
+      if (portErrorSign.Visible)
+        return false;
+      if (rootPwdErrorSign.Visible)
+        return false;
+      if (serviceErrorSign.Visible)
+        return false;
       return true;
     }
 

=== modified file 'WexInstaller.Core/InstallerConfiguration.cs'
--- a/WexInstaller.Core/InstallerConfiguration.cs	2011-03-10 15:47:49 +0000
+++ b/WexInstaller.Core/InstallerConfiguration.cs	2011-03-18 10:29:04 +0000
@@ -1,208 +1,207 @@
 using System;
 using System.Collections.Generic;
-using System.Text;
-using System.Xml.Serialization;
+using System.Diagnostics;
+using System.Drawing;
 using System.IO;
-using System.Reflection;
-using System.Drawing;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
 using System.Net;
+using System.Xml.Serialization;
+
 using MySQL.Utilities.SysUtils;
 
 namespace WexInstaller.Core
 {
-    public sealed class InstallerConfiguration
-    {
-        private static InstallerConfigurationData Instance = new InstallerConfigurationData();
-        private static WebClient Wc = new WebClient();
-
-        // Indicates if this configuration was loaded from file or is just a default config.
-        private static bool isDefault = true;
-
-        #region Properties
-
-        public static bool DisplayLicenseAgreement
-        {
-            get { return Instance.LicenseAgreement > 0; }
-            set { if (value) Instance.LicenseAgreement = 1; else Instance.LicenseAgreement = 0; }
-        }
-
-        public static Point Location
-        {
-            get { return Instance.Location; }
-            set { Instance.Location = value; }
-        }
-
-        public static string ProposedInstallationPath { get; set; }
-
-        public static string HomeDir { get; set; }
-
-        public static bool NewInstall
-        {
-            get { return true; }
-        }
-
-        public static List<UpdateURL> UpdateURLs
-        {
-            get { return Instance.UpdateURLs; }
-            set { Instance.UpdateURLs = value; }
-        }
-
-        public static int UpdateTimeoutMilliseconds
-        {
-            get { return Instance.UpdateTimeoutMilliseconds; }
-            set { Instance.UpdateTimeoutMilliseconds = value; }
-        }
-
-        public static int UpdateCheckFrequency 
-        {
-            get { return Instance.UpdateCheckFrequency; }
-            set { Instance.UpdateCheckFrequency = value; }
-        }
-
-        public static string ProductCachePath
-        {
-            get { return Instance.ProductCachePath; }
-            set { Instance.ProductCachePath = value; }
-        }
-
-        public static string InstallationRoot 
-        {
-            get { return Instance.InstallationRoot; }
-            set { Instance.InstallationRoot = value; }
-        }
-
-        public static string ProductCode
-        {
-            get { return Instance.ProductCode; }
-            set { Instance.ProductCode = value; }
-        }
-
-        private static string ConfigFile
-        {
-            get { return String.Format("{0}\\config.xml", HomeDir); }
-        }
-
-        public static string ProductsManifest
-        {
-            get { return String.Format("{0}\\products.xml", HomeDir); }
-        }
-
-        public static string TempProductsManifest
-        {
-            get { return String.Format("{0}\\products.xml.temp", HomeDir); }
-        }
-
-        public static string TemplateName
-        {
-            get { return String.Format("{0}\\my-template.ini", HomeDir); }
-        }
-
-        public static string TempManifest
-        {
-            get { return String.Format("{0}\\new_products.xml", HomeDir);}
-        }
-
-        public static bool IsDefault
-        {
-            get { return isDefault;  }
-        }
-
-        #endregion
-
-        public static void Save()
-        {
-            XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
-            TextWriter w = new StreamWriter(ConfigFile);
-            s.Serialize(w, Instance);
-            w.Close();
-        }
-
-        public static void Load()
-        {
-          if (HomeDir == null || HomeDir == String.Empty)
-              HomeDir = String.Format("{0}\\MySQL\\MySQL Universal Installer", 
-                                      Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
-
-          if (!Directory.Exists(HomeDir))
-            Directory.CreateDirectory(HomeDir);
-
-          if (File.Exists(ConfigFile))
-          {
-            XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
-            TextReader r = new StreamReader(ConfigFile);
-            Instance = (InstallerConfigurationData)s.Deserialize(r);
-            isDefault = false;
-          }
-          else
-          {
-            Instance.LicenseAgreement = 1;
-            Instance.UpdateCheckFrequency = 7;
-            // XXX: is this a constant GUID or rather dynamically created?
-            Instance.ProductCode = "{303BA173-69F6-4DC3-B11B-96B104C45BF9}";
-          }
-
-          // Consider incomplete/corrupt/non-existing config file.
-          // Set useful defaults for important values.
-          if (Instance.UpdateURLs.Count == 0)
-          {
-              UpdateURL url = new UpdateURL("http://wb.mysql.com/installer/products.xml");
-              Instance.UpdateURLs.Add(url);
-          }
-
-          Instance.UpdateTimeoutMilliseconds = 10000;
-
-          // Product cache and installation root defaults and sanity checks.
-          if (Instance.ProductCachePath == null || Instance.ProductCachePath == String.Empty)
-            Instance.ProductCachePath = Path.Combine(HomeDir, @"Product Cache\");
-          if (!Instance.ProductCachePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
-            Instance.ProductCachePath += Path.DirectorySeparatorChar;
-          if (!Directory.Exists(Instance.ProductCachePath))
-            Directory.CreateDirectory(Instance.ProductCachePath);
-
-          if (Instance.InstallationRoot == null || Instance.InstallationRoot == String.Empty)
-            Instance.InstallationRoot = Path.Combine(
-              Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
-              @"MySQL\MySQL Universal Installer\");
-          if (!Instance.InstallationRoot.EndsWith(Path.DirectorySeparatorChar.ToString()))
-            Instance.InstallationRoot += Path.DirectorySeparatorChar;
-        }
-
-        public static bool IsWow64()
-        {
-            bool isWow64 = false;
-
-            Win32.IsWow64Process(Process.GetCurrentProcess().Handle, out isWow64);
-
-            return isWow64;
-        }
-    }
-
-    [XmlRoot("Configuration")]
-    public class InstallerConfigurationData
-    {
-        public List<UpdateURL> UpdateURLs { get; set; }
-        public int UpdateTimeoutMilliseconds { get; set; }
-        public int UpdateCheckFrequency { get; set; }
-        public string ProductCachePath { get; set; }
-        public string InstallationRoot { get; set; }
-        public int LicenseAgreement { get; set; }
-        public Point Location { get; set; }
-        public string ProductCode { get; set; }
-    }
-
-    public class UpdateURL
-    {
-        public UpdateURL()
-        {
-            URL = "";
-        }
-
-        public UpdateURL(string url)
-        {
-            URL = url;
-        }
-        public string URL { get; set; }
-    }
+  public sealed class InstallerConfiguration
+  {
+    private static InstallerConfigurationData instance = new InstallerConfigurationData();
+    private static WebClient webClient = new WebClient();
+
+    // Indicates if this configuration was loaded from file or is just a default config.
+    private static bool isDefault = true;
+
+    #region Properties
+
+    public static bool DisplayLicenseAgreement
+    {
+      get { return instance.LicenseAgreement > 0; }
+      set { if (value) instance.LicenseAgreement = 1; else instance.LicenseAgreement = 0; }
+    }
+
+    public static Point Location
+    {
+      get { return instance.Location; }
+      set { instance.Location = value; }
+    }
+
+    public static string ProposedInstallationPath { get; set; }
+
+    public static string HomeDir { get; set; }
+
+    public static bool NewInstall
+    {
+      get { return true; }
+    }
+
+    public static List<UpdateURL> UpdateURLs
+    {
+      get { return instance.UpdateURLs; }
+      set { instance.UpdateURLs = value; }
+    }
+
+    public static int UpdateTimeoutMilliseconds
+    {
+      get { return instance.UpdateTimeoutMilliseconds; }
+      set { instance.UpdateTimeoutMilliseconds = value; }
+    }
+
+    public static int UpdateCheckFrequency 
+    {
+      get { return instance.UpdateCheckFrequency; }
+      set { instance.UpdateCheckFrequency = value; }
+    }
+
+    public static string ProductCachePath
+    {
+      get { return instance.ProductCachePath; }
+      set { instance.ProductCachePath = value; }
+    }
+
+    public static string InstallationRoot 
+    {
+      get { return instance.InstallationRoot; }
+      set { instance.InstallationRoot = value; }
+    }
+
+    public static string ProductCode
+    {
+      get { return instance.ProductCode; }
+      set { instance.ProductCode = value; }
+    }
+
+    private static string ConfigFile
+    {
+      get { return String.Format("{0}\\config.xml", HomeDir); }
+    }
+
+    public static string ProductsManifest
+    {
+      get { return String.Format("{0}\\products.xml", HomeDir); }
+    }
+
+    public static string TempProductsManifest
+    {
+      get { return String.Format("{0}\\products.xml.temp", HomeDir); }
+    }
+
+    public static string TemplateName
+    {
+      get { return String.Format("{0}\\my-template.ini", HomeDir); }
+    }
+
+    public static string TempManifest
+    {
+      get { return String.Format("{0}\\new_products.xml", HomeDir);}
+    }
+
+    public static bool IsDefault
+    {
+      get { return isDefault;  }
+    }
+
+    public static string ActiveCatalog
+    {
+      get { return instance.ActiveCatalog; }
+      set { instance.ActiveCatalog = value; }
+    }
+    #endregion
+
+    public static void Save()
+    {
+      XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
+      TextWriter w = new StreamWriter(ConfigFile);
+      s.Serialize(w, instance);
+      w.Close();
+    }
+
+    public static void Load()
+    {
+      Logger.LogInformation("Loading configuration.");
+
+      if (HomeDir == null || HomeDir == String.Empty)
+        HomeDir = String.Format("{0}\\MySQL\\MySQL Universal Installer", 
+          Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
+
+      if (!Directory.Exists(HomeDir))
+        Directory.CreateDirectory(HomeDir);
+
+      if (File.Exists(ConfigFile))
+      {
+        Logger.LogInformation("Configuration file found.");
+        XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
+        TextReader r = new StreamReader(ConfigFile);
+        instance = (InstallerConfigurationData)s.Deserialize(r);
+        isDefault = false;
+      }
+      else
+      {
+        instance.LicenseAgreement = 1;
+        instance.UpdateCheckFrequency = 7;
+        // XXX: is this a constant GUID or rather dynamically created?
+        instance.ProductCode = "{303BA173-69F6-4DC3-B11B-96B104C45BF9}";
+      }
+
+      // Consider incomplete/corrupt/non-existing config file.
+      // Set useful defaults for important values.
+      if (instance.UpdateURLs.Count == 0)
+      {
+        UpdateURL url = new UpdateURL("http://wb.mysql.com/installer/products.xml");
+        instance.UpdateURLs.Add(url);
+      }
+
+      Logger.LogInformation("Configuration sanity checks and default values.");
+      instance.UpdateTimeoutMilliseconds = 10000;
+
+      // Product cache and installation root defaults and sanity checks.
+      if (string.IsNullOrEmpty(instance.ProductCachePath))
+        instance.ProductCachePath = Path.Combine(HomeDir, @"Product Cache\");
+      if (!instance.ProductCachePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
+        instance.ProductCachePath += Path.DirectorySeparatorChar;
+      if (!Directory.Exists(instance.ProductCachePath))
+        Directory.CreateDirectory(instance.ProductCachePath);
+
+      if (string.IsNullOrEmpty(instance.InstallationRoot))
+        instance.InstallationRoot = Path.Combine(
+          Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
+          @"MySQL\MySQL Universal Installer\");
+      if (!instance.InstallationRoot.EndsWith(Path.DirectorySeparatorChar.ToString()))
+        instance.InstallationRoot += Path.DirectorySeparatorChar;
+    }
+  }
+
+  [XmlRoot("Configuration")]
+  public class InstallerConfigurationData
+  {
+    public List<UpdateURL> UpdateURLs { get; set; }
+    public int UpdateTimeoutMilliseconds { get; set; }
+    public int UpdateCheckFrequency { get; set; }
+    public string ProductCachePath { get; set; }
+    public string InstallationRoot { get; set; }
+    public int LicenseAgreement { get; set; }
+    public Point Location { get; set; }
+    public string ProductCode { get; set; }
+    public string ActiveCatalog { get; set; }
+  }
+
+  public class UpdateURL
+  {
+    public UpdateURL()
+    {
+      URL = "";
+    }
+
+    public UpdateURL(string url)
+    {
+      URL = url;
+    }
+    public string URL { get; set; }
+  }
 }

=== modified file 'WexInstaller.Core/Package.cs'
--- a/WexInstaller.Core/Package.cs	2011-02-08 21:28:42 +0000
+++ b/WexInstaller.Core/Package.cs	2011-03-18 10:29:04 +0000
@@ -1,16 +1,16 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Text;
 using System.Xml.Serialization;
 using Microsoft.Win32;
-using System.Diagnostics;
 
 namespace WexInstaller.Core
 {
     public class Package
     {
-        private string PackageCode;
+        private string packageCode;
         private FileVersionInfo msiVersion;
 
         [XmlAttribute("type")]
@@ -25,8 +25,8 @@
         [XmlAttribute("id")]
         public string Id
         {
-            get { return PackageCode; }
-            set { PackageCode = value; UpdateOptionalParameters(); }
+            get { return packageCode; }
+            set { packageCode = value; UpdateOptionalParameters(); }
         }
 
         [XmlAttribute("thisVersion")]

=== modified file 'WexInstaller.Core/Product.cs'
--- a/WexInstaller.Core/Product.cs	2011-03-17 15:51:58 +0000
+++ b/WexInstaller.Core/Product.cs	2011-03-18 10:29:04 +0000
@@ -59,9 +59,39 @@
 
     public List<Package> Packages { get; set; }
 
+    public PackageArchitecture Architecture
+    {
+      get { return GetPackage().Architecture; }
+    }
+
     public string TitleWithVersion
     {
-      get { return String.Format("{0} {1}", Title, GetPackage().ThisVersion); }
+      get
+      {
+#if DEBUG
+        return TitleWithVersionAndArchitecture;
+#else
+        return String.Format("{0} {1}", Title, GetPackage().ThisVersion);
+#endif
+      }
+    }
+
+    public string TitleWithVersionAndArchitecture
+    {
+      get
+      {
+        string architecture = "";
+        switch (GetPackage().Architecture)
+        {
+          case PackageArchitecture.X86:
+            architecture = " (32-Bit)";
+            break;
+          case PackageArchitecture.X64:
+            architecture = " (64-Bit)";
+            break;
+        }
+        return String.Format("{0} {1}{2}", Title, GetPackage().ThisVersion, architecture);
+      }
     }
 
     public ProductConfigurationController Controller

=== modified file 'WexInstaller.Core/ProductCatalog.cs'
--- a/WexInstaller.Core/ProductCatalog.cs	2011-02-08 21:28:42 +0000
+++ b/WexInstaller.Core/ProductCatalog.cs	2011-03-18 10:29:04 +0000
@@ -1,69 +1,135 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.Generic;
 using System.Xml.Serialization;
-using System.Runtime.Serialization;
 
 namespace WexInstaller.Core
 {
-    public class ProductCatalog
-    {
-        [XmlAttribute("id")]
-        public string Id;
-        [XmlAttribute("name")]
-        public string Name;
-        [XmlAttribute("description")]
-        public string Description;
-        [XmlAttribute("commercial")]
-        public bool Commercial;
-        [XmlAttribute("default")]
-        public bool Default;
-        [XmlArray("SetupTypes")]
-        public List<SetupType> SetupTypes;
-        [XmlArray("CatalogProducts")]
-        public List<CatalogProduct> Products;
-    }
-
-    public class CatalogProduct
-    {
-        [XmlIgnore]
-        public Product ReferencedProduct;
-
-        [XmlAttribute("productId")]
-        public string ProductId;
-
-        [XmlAttribute("setupTypeFlags")]
-        public int SetupTypeFlag;
-    }
-
-    public enum SetupTypeFlag : int
-    {
-        Full=64,
-        Custom=128
-    }
-
-    public class SetupType
-    {
-        [XmlAttribute("flag")]
-        public int Flag;
-        [XmlAttribute("name")]
-        public string Name;
-        [XmlAttribute("description")]
-        public string Description;
-
-        public bool IsFull
-        {
-            get { return Flag == (int)SetupTypeFlag.Full; }
-        }
-
-        public bool IsCustom
-        {
-            get { return Flag == (int)SetupTypeFlag.Custom; }
-        }
-
-        public bool Includes(CatalogProduct product)
-        {
-            return IsFull || ((product.SetupTypeFlag & Flag) != 0);
-        }
-    }
+  /// <summary>
+  /// Represents the architecture type of the contained products.
+  /// </summary>
+  public enum CatalogArchitecture
+  {
+    Unknown,
+    X86,
+    X64,
+    Any,
+    Mixed
+  }
+
+  public class ProductCatalog
+  {
+    [XmlAttribute("id")]
+    public string Id;
+    [XmlAttribute("name")]
+    public string Name;
+    [XmlAttribute("description")]
+    public string Description;
+    [XmlAttribute("commercial")]
+    public bool Commercial;
+    [XmlAttribute("default")]
+    public bool Default;
+    [XmlArray("SetupTypes")]
+    public List<SetupType> SetupTypes;
+    [XmlArray("CatalogProducts")]
+    public List<CatalogProduct> Products;
+
+    private CatalogArchitecture architecture = CatalogArchitecture.Unknown;
+    [XmlIgnore]
+    public CatalogArchitecture Architecture
+    {
+      get
+      {
+        if (architecture == CatalogArchitecture.Unknown && Products.Count > 0)
+        {
+          foreach (CatalogProduct product in Products)
+          {
+            CatalogArchitecture currentArchitecture = CatalogArchitecture.Unknown;
+            switch (product.ReferencedProduct.Architecture)
+            {
+              case PackageArchitecture.X86:
+                currentArchitecture = CatalogArchitecture.X86;
+                break;
+              case PackageArchitecture.X64:
+                currentArchitecture = CatalogArchitecture.X64;
+                break;
+              case PackageArchitecture.Any:
+                currentArchitecture = CatalogArchitecture.Any;
+                break;
+            }
+
+            if (architecture == CatalogArchitecture.Unknown)
+              architecture = currentArchitecture;
+            else
+              if (architecture != currentArchitecture)
+              {
+                architecture = CatalogArchitecture.Mixed;
+                break;
+              }
+          }
+        }
+
+        return architecture;
+      }
+    }
+
+    /// <summary>
+    /// Determines if any of the contained products requires a 64 bit architecture.
+    /// This does not include those with "Any" set. This does not *require* a 64 bit arch.
+    /// </summary>
+    public bool Requires64BitArchitecture
+    {
+      get
+      {
+        if (architecture == CatalogArchitecture.X64)
+          return true;
+        foreach (CatalogProduct product in Products)
+          if (product.ReferencedProduct.Architecture == PackageArchitecture.X64)
+            return true;
+
+        return false;
+      }
+    }
+  }
+
+  public class CatalogProduct
+  {
+    [XmlIgnore]
+    public Product ReferencedProduct;
+
+    [XmlAttribute("productId")]
+    public string ProductId;
+
+    [XmlAttribute("setupTypeFlags")]
+    public int SetupTypeFlag;
+  }
+
+  public enum SetupTypeFlag : int
+  {
+    Full=64,
+    Custom=128
+  }
+
+  public class SetupType
+  {
+    [XmlAttribute("flag")]
+    public int Flag;
+    [XmlAttribute("name")]
+    public string Name;
+    [XmlAttribute("description")]
+    public string Description;
+
+    public bool IsFull
+    {
+      get { return Flag == (int)SetupTypeFlag.Full; }
+    }
+
+    public bool IsCustom
+    {
+      get { return Flag == (int)SetupTypeFlag.Custom; }
+    }
+
+    public bool Includes(CatalogProduct product)
+    {
+      return IsFull || ((product.SetupTypeFlag & Flag) != 0);
+    }
+  }
 }

=== modified file 'WexInstaller.Core/ProductFeature.cs'
--- a/WexInstaller.Core/ProductFeature.cs	2011-03-03 15:21:07 +0000
+++ b/WexInstaller.Core/ProductFeature.cs	2011-03-18 10:29:04 +0000
@@ -26,11 +26,11 @@
     [XmlIgnore]
     public Image LargeIcon
     {
-        get
-        {
-          EnsureIconsAreLoaded();
-          return largeIcon;
-        }
+      get
+      {
+      EnsureIconsAreLoaded();
+      return largeIcon;
+      }
     }
 
     [XmlIgnore]
@@ -106,76 +106,77 @@
     [XmlIgnore]
     public bool ProposedInstalled
     {
-        get { return proposedInstalled; }
-        set { SetProposedInstalled(value); }
+      get { return proposedInstalled; }
+      set { SetProposedInstalled(value); }
     }
 
     [XmlIgnore]
     public int FeatureCount
     {
-        get
+      get
+      {
+        int count = 0;
+        foreach (ProductFeature f in Features)
         {
-            int count = 0;
-            foreach (ProductFeature f in Features)
-            {
-                count++;
-                count += f.FeatureCount;
-            }
-            return count;
+          count++;
+          count += f.FeatureCount;
         }
+        return count;
+      }
     }
 
     public ProductFeature()
     {
-        Features = new List<ProductFeature>();
+      Features = new List<ProductFeature>();
     }
 
     protected virtual void SetProposedInstalled(bool shouldInstall)
     {
-        if (shouldInstall == proposedInstalled) return;
-        proposedInstalled = shouldInstall;
-        foreach (ProductFeature f in Features)
-        {
-            f.ProposedInstalled = shouldInstall;
-        }
+      if (shouldInstall == proposedInstalled)
+        return;
+      proposedInstalled = shouldInstall;
+      foreach (ProductFeature f in Features)
+        f.ProposedInstalled = shouldInstall;
     }
 
     public bool HasChanges()
     {
-        bool hasChanges;
-        hasChanges = Installed != ProposedInstalled;
-        foreach (ProductFeature feature in Features)
-            hasChanges |= feature.HasChanges();
-        return hasChanges;
+      bool hasChanges;
+      hasChanges = Installed != ProposedInstalled;
+      foreach (ProductFeature feature in Features)
+        hasChanges |= feature.HasChanges();
+      return hasChanges;
     }
 
     internal void ProcessFeatures(List<ProductFeature> toAdd, List<ProductFeature> toRemove)
     {
-        foreach (ProductFeature f in Features)
+      foreach (ProductFeature f in Features)
+      {
+        if (f.Installed != f.ProposedInstalled)
         {
-            if (f.Installed != f.ProposedInstalled)
-            {
-                if (!f.Installed) toAdd.Add(f);
-                else toRemove.Add(f);
-            }
-            f.ProcessFeatures(toAdd, toRemove);
+          if (!f.Installed)
+            toAdd.Add(f);
+          else
+            toRemove.Add(f);
         }
+        f.ProcessFeatures(toAdd, toRemove);
+      }
     }
 
     public virtual long GetInstallationSizeEstimate()
     {
-        long sizeEst = 0;
-        foreach (ProductFeature f in Features)
-            sizeEst += f.SizeEstimate;
-        sizeEst += SizeEstimate;
-        return sizeEst;
+      long sizeEst = 0;
+      foreach (ProductFeature f in Features)
+        sizeEst += f.SizeEstimate;
+      sizeEst += SizeEstimate;
+      return sizeEst;
     }
 
     public override void SetParent(ProductElement parent)
     {
-        base.SetParent(parent);
-        foreach (ProductFeature f in Features)
-            f.SetParent(this);
+      base.SetParent(parent);
+      foreach (ProductFeature f in Features)
+        f.SetParent(this);
     }
   }
 }

=== modified file 'WexInstaller.Core/ProductManager.cs'
--- a/WexInstaller.Core/ProductManager.cs	2011-03-10 03:08:26 +0000
+++ b/WexInstaller.Core/ProductManager.cs	2011-03-18 10:29:04 +0000
@@ -6,6 +6,8 @@
 using System.Threading;
 using System.Xml.Serialization;
 
+using MySQL.Utilities.SysUtils;
+
 namespace WexInstaller.Core
 {
   public delegate void DownloadManifestProgressHandler(object sender, DownloadProgressChangedEventArgs de);
@@ -30,8 +32,21 @@
     private static bool CatalogProductsUpgrade { get; set; }
     public static bool ProductsInstalled { get; private set; }
     public static bool ProductsUpgrade { get; private set; }
-    public static ProductCatalog ActiveCatalog { get; set; }
-    public static string DefaultCatalog { get; set; }
+    public static ProductCatalog DefaultCatalog { get; set; }
+
+    private static ProductCatalog activeCatalog = null;
+    public static ProductCatalog ActiveCatalog
+    {
+      get { return activeCatalog; }
+      set
+      {
+        activeCatalog = value;
+        if (value != null)
+          InstallerConfiguration.ActiveCatalog = value.Id;
+        else
+          InstallerConfiguration.ActiveCatalog = null;
+      }
+    }
 
     private static ProductManifest ObjectifyManifest(string fileName)
     {
@@ -93,22 +108,65 @@
             throw new InvalidOperationException();
         }
 
-      // Default to first catalog and then see if we have a catalog file
-      // that gives us a different default
-      string defaultCatalog = GetDefaultCatalogIfAny();
-      ActiveCatalog = null;
-      if (defaultCatalog != null)
-      {
-        foreach (ProductCatalog cat in manifest.ProductCatalogs)
-          if (cat.Id == defaultCatalog)
-          {
-            ActiveCatalog = cat;
-            break;
-          }
-      }
+      // Set a good active catalog. Use either what was active last, is given on the command line
+      // or pick a good default. Consider OS architecture when determining an own default.
+      string givenCatalogId = null;
+      string[] args = Environment.GetCommandLineArgs();
+      if (args.Length > 1)
+      {
+        Logger.LogInformation(string.Format("Using default catalog from command line {0}.", args[1]));
+        givenCatalogId = args[1]; // This should be the default catalog name (not id).
+      }
+
+      // If no default catalog is given then use the one stored in the settings.
+      if (givenCatalogId == null)
+        givenCatalogId = InstallerConfiguration.ActiveCatalog;
+
+      DefaultCatalog = null;
+      if (givenCatalogId != null)
+      {
+        foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+          if (catalog.Id == givenCatalogId)
+          {
+            DefaultCatalog = catalog;
+            break;
+          }
+      }
+
+      // Sanity check: see if the default is for a 64 bit OS but we are only on 32 bit.
+      bool is64Bit = Win32.Is64BitOS();
+      if (DefaultCatalog != null && DefaultCatalog.Requires64BitArchitecture && !is64Bit)
+      {
+        Logger.LogInformation("Invalid default catalog architecture given. Switching to 32 bit.");
+
+        // Change the default catalog to the 32 bit version.
+        foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+          if (catalog.Name == DefaultCatalog.Name && !catalog.Requires64BitArchitecture)
+          {
+            DefaultCatalog = catalog;
+            break;
+          }
+      }
+
+      if (DefaultCatalog == null)
+      {
+        // If there was no catalog given (or none found/stored) use the first catalog from the manifest
+        // which corresponds to our current OS architecture.      
+        foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+          if (catalog.Requires64BitArchitecture == is64Bit)
+          {
+            DefaultCatalog = catalog;
+            break;
+          }
+      }
+
+      // The default catalog is also the initial active catalog. If there was a stored catalog
+      // then it is already used for the default catalog (if no other was given on the command line).
+      ActiveCatalog = DefaultCatalog;
+
       if (ActiveCatalog != null)
       {
-        // setup the Installed and IsUpgrade global variables based
+        // Setup the Installed and IsUpgrade global variables based
         // on what from the active catalog is installed.
         foreach (CatalogProduct cp in ActiveCatalog.Products)
         {
@@ -116,6 +174,8 @@
           CatalogProductsUpgrade |= cp.ReferencedProduct.IsUpgrade;
         }
       }
+      else
+        Logger.LogError("Could not set a default catalog.");
     }
 
     public static bool IsNewSetup()
@@ -138,18 +198,6 @@
       }
     }
 
-    private static string GetDefaultCatalogIfAny()
-    {
-      // if ActiveCatalog != null, then this isn't the the first 
-      // time we have run so we always use default in that case
-      if (ActiveCatalog != null)
-        return null;
-      string[] args = Environment.GetCommandLineArgs();
-      if (args.Length < 2)
-        return null;
-      return args[1];   // this should be the default catalog name
-    }
-
     private static void LoadManifestWithCheckForTemp()
     {
       // first we need to see if there is any temp manifest file to check

=== modified file 'WexInstaller.Core/WexInstaller.Core.csproj'
--- a/WexInstaller.Core/WexInstaller.Core.csproj	2011-03-03 15:21:07 +0000
+++ b/WexInstaller.Core/WexInstaller.Core.csproj	2011-03-18 10:29:04 +0000
@@ -37,6 +37,7 @@
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Management" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml" />
   </ItemGroup>

=== modified file 'WexInstaller.Core/Win32.cs'
--- a/WexInstaller.Core/Win32.cs	2011-03-10 15:47:49 +0000
+++ b/WexInstaller.Core/Win32.cs	2011-03-18 10:29:04 +0000
@@ -5,6 +5,7 @@
 using System.Diagnostics;
 using Microsoft.Win32.SafeHandles;
 using System.Drawing;
+using System.Management;
 
 namespace MySQL.Utilities.SysUtils
 {
@@ -3092,6 +3093,27 @@
       }
     }
 
+    /// <summary>
+    /// Determines if we are currently running on a 64 Bit OS.
+    /// </summary>
+    public static bool Is64BitOS()
+    {
+      ManagementObjectSearcher searcher =
+        new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_OperatingSystem");
+      foreach (ManagementObject wmi in searcher.Get())
+      {
+        // There is only one object in the returned result set (as we are on one OS only)
+        // though the principles of working with WMI dictate the handling we need here.
+        var architecture = wmi.GetPropertyValue("OSArchitecture");
+        if (architecture == null)
+          return false; // Not available before Vista/Win 2008,
+
+        return "64-bit".Equals(architecture);
+      }
+
+      return false;
+    }
+
     #endregion
 
     #region Console handling

=== modified file 'WexInstaller/Controls/FeatureBox.cs'
--- a/WexInstaller/Controls/FeatureBox.cs	2011-03-03 15:21:07 +0000
+++ b/WexInstaller/Controls/FeatureBox.cs	2011-03-18 10:29:04 +0000
@@ -1,178 +1,290 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Drawing;
-using System.Text;
 using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+
 using WexInstaller.Core;
-using System.Windows.Forms.VisualStyles;
 
 namespace WexInstaller.Controls
 {
-    public partial class FeatureBox : UserControl
-    {
-        private const int HEADER_HEIGHT = 44;
-
-        private ProductElement selectedObject;
-        private Font largeFont;
-        private Font smallFont;
-        private Size CBGlyphSize;
-
-        public FeatureBox()
-        {
-            InitializeComponent();
-            largeFont = new Font(Font, FontStyle.Bold);
-            smallFont = new Font(Font.FontFamily, (float)(Font.SizeInPoints * .85));
-        }
-
-        internal FeatureTreeView FeatureTree { get; set; }
-
-        public ProductElement SelectedObject
-        {
-            get { return selectedObject; }
-            set 
-            { 
-                selectedObject = value;
-                UpdateFeatureList();
-                Invalidate(ClientRectangle);
-            }
-        }
-
-        private void UpdateFeatureList()
-        {
-            featureList.Nodes.Clear();
-            if (SelectedObject == null) return;
-
-            if (SelectedObject is Product)
-                PopulateProduct();
-            else
-                PopulateProductCategory();
-        }
-
-        private void PopulateProduct()
-        {
-            Product p = SelectedObject as Product;
-            List<ProductFeature> productFeatures = p.GetProductFeatures();
-
-            foreach (ProductFeature feature in productFeatures)
-            {
-                if (feature.Display != "0")
-                {
-                    if (feature.HasComponents != null && feature.HasComponents.Length > 0)
-                    {
-                        TreeNode node = featureList.Nodes.Add(feature.Title);
-                        node.Tag = feature;
-                    }
-
-                    foreach (ProductFeature childFeature in feature.Features)
-                    {
-                        if (childFeature.Display != "0")
-                        {
-                            if (childFeature.HasComponents.Length > 0)
-                            {
-                                TreeNode node = featureList.Nodes.Add(childFeature.Title);
-                                node.Tag = childFeature;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private void PopulateProductCategory()
-        {
-            ProductCategory pc = SelectedObject as ProductCategory;
-            if (pc != null)
-            {
-                foreach (Product p in pc.Products)
-                {
-                    TreeNode node = featureList.Nodes.Add(p.TitleWithVersion);
-                    node.Tag = p;
-                }
-            }
-        }
-
-        protected override void OnPaint(PaintEventArgs e)
-        {
-            base.OnPaint(e);
-
-            if (e.ClipRectangle.Top < HEADER_HEIGHT)
-                PaintHeader(e.Graphics);
-        }
-
-        private void PaintHeader(Graphics g)
-        {
-          Brush grayBrush = new SolidBrush(Color.LightGray);
-          Brush whiteBrush = new SolidBrush(Color.White);
-          Brush blackBrush = new SolidBrush(Color.Black);
-
-          g.FillRectangle(grayBrush, 0, 0, Width, HEADER_HEIGHT);
-
-          if (SelectedObject == null) return;
+  public partial class FeatureBox : UserControl
+  {
+    #region Members and constants
+
+    private const int HEADER_HEIGHT = 44;
+
+    private ProductElement selectedObject;
+    private Font largeFont;
+    private Font smallFont;
+    private Size CBGlyphSize;
+
+    #endregion
+
+    #region Construction and setup
+
+    public FeatureBox()
+    {
+      InitializeComponent();
+      largeFont = new Font(Font, FontStyle.Bold);
+      smallFont = new Font(Font.FontFamily, (float)(Font.SizeInPoints * .85));
+    }
+
+    #endregion
+
+    #region Properties
+
+    internal FeatureTreeView FeatureTree { get; set; }
+
+    public ProductElement SelectedObject
+    {
+      get { return selectedObject; }
+      set 
+      { 
+        selectedObject = value;
+        UpdateFeatureList();
+        Invalidate(ClientRectangle);
+      }
+    }
+
+    public ProductCatalog Catalog { get; set; }
+
+    // These two are mutually exclusive, so an enum seems a good alternative.
+    // Having two bools makes handling a lot simpler, however.
+    public bool ListAllItems { get; set; }
+    public bool ListInstalledItems { get; set; }
+
+    #endregion
+
+    #region Application logic
+
+    private void UpdateFeatureList()
+    {
+      featureList.Nodes.Clear();
+      if (SelectedObject == null)
+        return;
+
+      if (SelectedObject is Product)
+        PopulateProduct();
+      else
+        PopulateProductCategory();
+    }
+
+    private void PopulateProduct()
+    {
+      Product p = SelectedObject as Product;
+      List<ProductFeature> productFeatures = p.GetProductFeatures();
+
+      foreach (ProductFeature feature in productFeatures)
+      {
+        if (feature.Display != "0")
+        {
+          if (feature.HasComponents != null && feature.HasComponents.Length > 0)
+          {
+            TreeNode node = featureList.Nodes.Add(feature.Title);
+            node.Tag = feature;
+          }
+
+          foreach (ProductFeature childFeature in feature.Features)
+          {
+            if (childFeature.Display != "0")
+            {
+              if (childFeature.HasComponents.Length > 0)
+              {
+                TreeNode node = featureList.Nodes.Add(childFeature.Title);
+                node.Tag = childFeature;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    private void PopulateProductCategory()
+    {
+      ProductCategory category = SelectedObject as ProductCategory;
+      if (category == null)
+        return;
+
+      bool showArchitecture = (FeatureTree.Architecture == CatalogArchitecture.Any);
+      List<Product> products = GetProducts(category);
+      foreach (Product product in products)
+      {
+        TreeNode node = featureList.Nodes.Add(
+          showArchitecture ? product.TitleWithVersionAndArchitecture : product.TitleWithVersion);
+        node.Tag = product;
+      }
+    }
+
+    /// <summary>
+    /// Returns a list of products which match the current criteria.
+    /// </summary>
+    /// <param name="category">Return only products which are part of this category.</param>
+    /// <returns>A list of products as specified by the parameters.</returns>
+    public List<Product> GetProducts(ProductCategory category)
+    {
+      List<Product> result = new List<Product>();
+
+      bool anyArchitecture = (FeatureTree.Architecture == CatalogArchitecture.Any);
+      PackageArchitecture packageArchitecture;
+      switch (FeatureTree.Architecture)
+      {
+        case CatalogArchitecture.X86:
+          packageArchitecture = PackageArchitecture.X86;
+          break;
+        case CatalogArchitecture.X64:
+          packageArchitecture = PackageArchitecture.X64;
+          break;
+        default:
+          packageArchitecture = PackageArchitecture.Any;
+          break;
+      }
+      if (ListAllItems || ListInstalledItems)
+      {
+        // List of products independent on a specific catalog. Just filter by architecture.
+        Dictionary<string, Product> products = new Dictionary<string, Product>();
+        foreach (Product p in category.Products)
+        {
+          bool architectureDoesNotMatter = anyArchitecture || p.Architecture == PackageArchitecture.Any;
+          if (architectureDoesNotMatter || p.Architecture == packageArchitecture)
+          {
+            if ((ListAllItems || p.Installed) && !products.ContainsKey(p.Name))
+              products[p.Name] = p;
+          }
+        }
+
+        result.AddRange(products.Values);
+      }
+      else
+      {
+        // Add products based on the products list in the given catalog.
+        // This catalog serves as base for the product list and might not represent the user's
+        // architecture choice. Additionally we need to consider several catalogs if Any is given
+        // as architecture.
+        List<ProductCatalog> catalogList = new List<ProductCatalog>();

+        bool needs64Bit = (packageArchitecture == PackageArchitecture.X64);
+        foreach (ProductCatalog candidate in ProductManager.Catalogs)
+        {
+          // Compare name first. Only catalogs with the same name participate here.
+          if (candidate.Name.Equals(Catalog.Name, StringComparison.InvariantCultureIgnoreCase))
+          {
+            if (anyArchitecture || candidate.Requires64BitArchitecture == needs64Bit)
+              catalogList.Add(candidate);
+          }
+        }
+
+        // No iterate over all categories and their products and see if any of the products matches
+        // any of the products in the reference catalog(s).
+        Dictionary<string, Product> products = new Dictionary<string, Product>();
+        foreach (Product p in category.Products)
+        {
+          foreach (ProductCatalog currentCatalog in catalogList)
+            foreach (CatalogProduct cp in currentCatalog.Products)
+              if (cp.ProductId.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase) &&
+                !products.ContainsKey(p.Name))
+                products[p.Name] = p;
+        }
+        result.AddRange(products.Values);
+      }
+
+      return result;
+    }
+
+    #endregion
+
+    #region Drawing
+
+    protected override void OnPaint(PaintEventArgs e)
+    {
+      base.OnPaint(e);
+
+      if (e.ClipRectangle.Top < HEADER_HEIGHT)
+        PaintHeader(e.Graphics);
+    }
+
+    private void PaintHeader(Graphics g)
+    {
+      Brush whiteBrush = new SolidBrush(Color.White);
+      Brush blackBrush = new SolidBrush(Color.Black);
+
+      using (Brush grayBrush = new SolidBrush(Color.LightGray))
+        g.FillRectangle(grayBrush, 0, 0, Width, HEADER_HEIGHT);
+
+      if (SelectedObject == null)
+        return;
             
-          if (SelectedObject.LargeIcon != null)
-            g.DrawImage(SelectedObject.LargeIcon, 6, 6);
-
-          Point textPt = new Point(50, 10);
-          g.DrawString(SelectedObject.Title, largeFont, whiteBrush, textPt);
-          textPt.Offset(-1, -1);
-          g.DrawString(SelectedObject.Title, largeFont, blackBrush, textPt);
-
-          textPt = new Point(50, 24);
-          g.DrawString(SelectedObject.Description, smallFont, blackBrush, textPt);
-        }
-
-        private void featureList_AfterCheck(object sender, TreeViewEventArgs e)
-        {
-            Product p = e.Node.Tag as Product;
-            if (p != null)
-            {
-                if (p.Installed) return;
-                p.ProposedInstalled = !p.ProposedInstalled;
-
-                List<ProductFeature> productFeatures = p.GetProductFeatures();
-                foreach (ProductFeature pf in productFeatures)
-                    pf.ProposedInstalled = p.ProposedInstalled;
-            }
-            else
-            {
-                ProductFeature pf = e.Node.Tag as ProductFeature;
-                pf.ProposedInstalled = !pf.ProposedInstalled;
-            }
-            featureList.Refresh();
-            if (FeatureTree != null)
-                FeatureTree.Refresh();
-        }
-
-        private void featureList_DrawNode(object sender, DrawTreeNodeEventArgs e)
-        {
-            if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0) return;
-
-            CheckBoxState state = CheckBoxState.UncheckedNormal;
-            Product p = (e.Node.Tag as Product);
-            if (p != null)
-            {
-                state = p.Installed ? CheckBoxState.CheckedDisabled :
-                    p.ProposedInstalled ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
-            }
-            else
-            {
-                ProductFeature pf = (e.Node.Tag as ProductFeature);
-                if (pf.ProposedInstalled) state = CheckBoxState.CheckedNormal;
-            }
-
-            if (CBGlyphSize.IsEmpty)
-                CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
-            Point location = new Point(e.Bounds.Left + CBGlyphSize.Width / 2,
-                e.Bounds.Top + ((featureList.ItemHeight - CBGlyphSize.Height) / 2));
-            CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
-
-            using (Brush blackBrush = new SolidBrush(Color.Black))
-            {
-                e.Graphics.DrawString(e.Node.Text, featureList.Font, blackBrush,
-                                      e.Bounds.X + (CBGlyphSize.Width*2),
-                                      e.Bounds.Y + ((featureList.ItemHeight - featureList.Font.Height) / 2));
-            }
-        }
-    }
+      if (SelectedObject.LargeIcon != null)
+        g.DrawImage(SelectedObject.LargeIcon, 6, 6);
+
+      Point textPt = new Point(50, 10);
+      g.DrawString(SelectedObject.Title, largeFont, whiteBrush, textPt);
+      textPt.Offset(-1, -1);
+      g.DrawString(SelectedObject.Title, largeFont, blackBrush, textPt);
+
+      textPt = new Point(50, 24);
+      g.DrawString(SelectedObject.Description, smallFont, blackBrush, textPt);
+    }
+
+    #endregion
+
+    #region Event handling
+
+    private void featureList_AfterCheck(object sender, TreeViewEventArgs e)
+    {
+      Product p = e.Node.Tag as Product;
+      if (p != null)
+      {
+        if (p.Installed) return;
+        p.ProposedInstalled = !p.ProposedInstalled;
+
+        List<ProductFeature> productFeatures = p.GetProductFeatures();
+        foreach (ProductFeature pf in productFeatures)
+            pf.ProposedInstalled = p.ProposedInstalled;
+      }
+      else
+      {
+        ProductFeature pf = e.Node.Tag as ProductFeature;
+        pf.ProposedInstalled = !pf.ProposedInstalled;
+      }
+      featureList.Refresh();
+      if (FeatureTree != null)
+        FeatureTree.Refresh();
+    }
+
+    private void featureList_DrawNode(object sender, DrawTreeNodeEventArgs e)
+    {
+      if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0)
+        return;
+
+      CheckBoxState state = CheckBoxState.UncheckedNormal;
+      Product p = (e.Node.Tag as Product);
+      if (p != null)
+      {
+        state = p.Installed ? CheckBoxState.CheckedDisabled :
+          p.ProposedInstalled ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
+      }
+      else
+      {
+        ProductFeature pf = (e.Node.Tag as ProductFeature);
+        if (pf.ProposedInstalled)
+          state = CheckBoxState.CheckedNormal;
+      }
+
+      if (CBGlyphSize.IsEmpty)
+        CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
+      Point location = new Point(e.Bounds.Left + CBGlyphSize.Width / 2,
+        e.Bounds.Top + ((featureList.ItemHeight - CBGlyphSize.Height) / 2));
+      CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
+
+      using (Brush blackBrush = new SolidBrush(Color.Black))
+      {
+        e.Graphics.DrawString(e.Node.Text, featureList.Font, blackBrush,
+                              e.Bounds.X + (CBGlyphSize.Width * 2),
+                              e.Bounds.Y + ((featureList.ItemHeight - featureList.Font.Height) / 2));
+      }
+    }
+
+    #endregion
+
+  }
 }

=== modified file 'WexInstaller/Controls/FeatureTreeView.cs'
--- a/WexInstaller/Controls/FeatureTreeView.cs	2011-03-03 15:21:07 +0000
+++ b/WexInstaller/Controls/FeatureTreeView.cs	2011-03-18 10:29:04 +0000
@@ -1,319 +1,329 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.Generic;
+using System.Drawing;
 using System.Windows.Forms;
-using System.Drawing;
 using System.Windows.Forms.VisualStyles;
-using System.Drawing.Imaging;
+
+using WexInstaller.Core;
 using WexInstaller.Properties;
-using WexInstaller.Core;
-using System.Diagnostics;
 
 namespace WexInstaller.Controls
 {
-    class FeatureTreeView : TreeView
-    {
-        private SolidBrush grayBrush { get; set; }
-        private SolidBrush blackBrush { get; set; }
-        private SolidBrush lightGrayBrush { get; set; }
-        private Font titleFont { get; set; }
-        private Size CBGlyphSize { get; set; }
-        private Size PlusMinusSize { get; set; }
-        private int CurrentWidth { get; set; }
-
-        public FeatureTreeView()
-            : base()
-        {
-            grayBrush = new SolidBrush(Color.WhiteSmoke);
-            blackBrush = new SolidBrush(Color.Black);
-            lightGrayBrush = new SolidBrush(Color.Gray);
-            titleFont = new Font("Tahoma", 8.25F, FontStyle.Bold);
-
-            DrawMode = TreeViewDrawMode.OwnerDrawAll;
-            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
-            UpdateStyles();
-        }
-
-        public TreeNode AddCategory(ProductCategory category)
-        {
-            TreeNode node = Nodes.Add(category.Title);
-            node.ToolTipText = category.Description;
-            node.Tag = category;
-            return node;
-        }
-
-        public void AddProduct(Product product, TreeNode parentNode)
-        {
-            TreeNode node = new TreeNode(product.TitleWithVersion);
-            node.ToolTipText = product.Description;
-            node.Tag = product;
-            if (parentNode == null)
-                Nodes.Add(node);
-            else
-                parentNode.Nodes.Add(node);
-        }
-
-        protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
-        {
-            int offset = GetOffset(e.Node);
-            Rectangle cbRect = new Rectangle();
-            cbRect.Location = new Point(offset+10, e.Node.Bounds.Top + ((ItemHeight - CBGlyphSize.Height) / 2));
-            cbRect.Size = CBGlyphSize;
-
-            Rectangle plusMinusRect = new Rectangle();
-            plusMinusRect.Location = new Point(CurrentWidth - 25, 
-                e.Node.Bounds.Top + ((ItemHeight - PlusMinusSize.Height) / 2));
-            plusMinusRect.Size = PlusMinusSize;
-
-            if (cbRect.Contains(e.Location))
-            {
-                ClickNode(e.Node);
-                Refresh();
-            }
-            else if (plusMinusRect.Contains(e.Location))
-            {
-                if (e.Node.IsExpanded)
-                    e.Node.Collapse();
-                else
-                    e.Node.Expand();
-            }
-            base.OnNodeMouseClick(e);
-        }
-
-        private void ClickNode(TreeNode node)
-        {
-            ProductCategory pc = node.Tag as ProductCategory;
-            if (pc != null)
-                ClickCategoryNode(pc);
-            else
-                ClickProductNode(node.Tag as Product);
-        }
-
-        private void ClickCategoryNode(ProductCategory cat)
-        {
-            foreach (Product p in cat.Products)
-            {
-                if (!p.Installed)
-                    p.ProposedInstalled = !p.ProposedInstalled;
-
-                List<ProductFeature> productFeatures = p.GetProductFeatures();
-                foreach (ProductFeature pf in productFeatures)
-                    pf.ProposedInstalled = p.ProposedInstalled;
-            }
-        }
-
-        private void ClickProductNode(Product p)
-        {
-            if (!p.Installed)
-                p.ProposedInstalled = !p.ProposedInstalled;
-
-            List<ProductFeature> productFeatures = p.GetProductFeatures();
-            foreach (ProductFeature pf in productFeatures)
-                pf.ProposedInstalled = p.ProposedInstalled;
-        }
-
-        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
-        {
-            if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0) return;
-
-            CurrentWidth = e.Bounds.Width;
-            DrawBackground(e);
-
-            Rectangle r = e.Bounds;
-            r.Offset(GetOffset(e.Node), 0);
-
-            DrawCheckbox(e, r);
-            if ((e.Node.Tag as ProductCategory) != null && ((e.Node.Tag as ProductCategory).Products.Count > 0))
-            {
-                DrawPlusMinus(e, r);
-            }
-            DrawState(e, r);
-            DrawText(e, r);
-        }
-
-        protected override void OnAfterExpand(TreeViewEventArgs e)
-        {
-            base.OnAfterExpand(e);
-            Invalidate();
-            Update();
-        }
-
-        protected override void OnAfterCollapse(TreeViewEventArgs e)
-        {
-            base.OnAfterCollapse(e);
-            Invalidate();
-            Update();
-        }
-
-        private CheckBoxState GetNodeCheckboxState(TreeNode node)
-        {
-            Product product = node.Tag as Product;
-            if (product !=null)
-                return GetStateForProduct(product);
-
-            List<ProductFeature> featureList = new List<ProductFeature>();
-            ProductCategory pc = node.Tag as ProductCategory;
-            foreach (Product p in pc.Products)
-            {
-                List<ProductFeature> productFeatures = p.GetProductFeatures();
-
-                foreach (ProductFeature pf in productFeatures)
-                {
-                    featureList.Add(pf);
-                }
-            }
-            return GetStateFromFeatureList(featureList);
-        }
-
-        private CheckBoxState GetStateForProduct(Product p)
-        {
-            List<ProductFeature> productFeatures = p.GetProductFeatures();

-            CheckBoxState state = GetStateFromFeatureList(productFeatures);
-            if (state == CheckBoxState.CheckedNormal || state == CheckBoxState.MixedNormal)
-            {
-                if (!p.ProposedInstalled)
-                    p.ProposedInstalled = true;
-            }
-            if (p.Installed)
-                state = (CheckBoxState)((int)state + 3);
-            return state;
-        }
-
-        private CheckBoxState GetStateFromFeatureList(List<ProductFeature> featureList)
-        {
-            bool allInstalled = true;
-            bool anyInstalled = false;
-            foreach (ProductFeature f in featureList)
-            {
-                allInstalled &= f.ProposedInstalled;
-                anyInstalled |= f.ProposedInstalled;
-            }
-            if (allInstalled) return CheckBoxState.CheckedNormal;
-            if (anyInstalled) return CheckBoxState.MixedNormal;
-            return CheckBoxState.UncheckedNormal;
-        }
-
-        private int GetOffset(TreeNode node)
-        {
-            return node.Level * 15;
-        }
-
-        private Image GetNodeIcon(TreeNode node)
-        {
-          while (node != null)
-          {
-            ProductCategory pc = node.Tag as ProductCategory;
-            if (pc != null)
-              return pc.SmallIcon;
-            Product p = node.Tag as Product;
-            if (p.SmallIcon != null)
-              return p.SmallIcon;
-            node = node.Parent;
-          }
-          return null;
-        }
-
-        private void DrawCheckbox(DrawTreeNodeEventArgs e, Rectangle r)
-        {
-            CheckBoxState state = GetNodeCheckboxState(e.Node);
-
-            if (CBGlyphSize.IsEmpty)
-                CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
-            int offset = (ItemHeight - CBGlyphSize.Height) / 2;
-            Point location = new Point(r.Left+10, r.Top + offset);
-
-            CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
-        }
-
-        private void DrawPlusMinus(DrawTreeNodeEventArgs e, Rectangle r)
-        {
-            Image displayImage = (e.Node.IsExpanded) ? Resources.minus_sign : Resources.plus_sign;
-            if (PlusMinusSize.IsEmpty)
-                PlusMinusSize = displayImage.Size;
-            int top = r.Top + ((ItemHeight - displayImage.Height) / 2);
-            int left = r.Left + r.Width - 25;
-
-            e.Graphics.DrawImageUnscaled(displayImage, left, top);
-        }
-
-        private void DrawText(DrawTreeNodeEventArgs e, Rectangle r)
-        {
-            e.Graphics.DrawString(e.Node.Text, titleFont, blackBrush,
-                                  r.Left + 62,
-                                  r.Top + ((ItemHeight - titleFont.Height) / 2));
-        }
-
-        private void DrawState(DrawTreeNodeEventArgs e, Rectangle r)
-        {
-            int top = r.Top;
-            int left = r.Left;
-
-            Image icon = GetNodeIcon(e.Node);
-            if (icon != null)
-              e.Graphics.DrawImage(icon, left + 32, top + 6);
-
-            //ProductCategory pc = e.Node.Tag as ProductCategory;
-            //int index = -1;
-           // if (pc == null)
-            //{
-              //  ProductFeature f = e.Node.Tag as ProductFeature;
+  class FeatureTreeView : TreeView
+  {
+    private SolidBrush grayBrush { get; set; }
+    private Size CBGlyphSize { get; set; }
+    private Size PlusMinusSize { get; set; }
+    private int CurrentWidth { get; set; }
+
+    public CatalogArchitecture Architecture { get; set; }
+
+    public FeatureTreeView()
+      : base()
+    {
+      grayBrush = new SolidBrush(Color.WhiteSmoke);
+
+      DrawMode = TreeViewDrawMode.OwnerDrawAll;
+      SetStyle(ControlStyles.DoubleBuffer, true);
+      SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+      SetStyle(ControlStyles.Opaque, true);
+      SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+      UpdateStyles();
+    }
+
+    public TreeNode AddCategory(ProductCategory category)
+    {
+      TreeNode node = Nodes.Add(category.Title);
+      node.ToolTipText = category.Description;
+      node.Tag = category;
+      return node;
+    }
+
+    /// <summary>
+    /// Adds a new product node to the treeview.
+    /// </summary>
+    /// <param name="product">The product for which the node is to be created.</param>
+    /// <param name="parentNode">The parent of the new node (to collect similar products into one area)</param>
+    public void AddProduct(Product product, TreeNode parentNode)
+    {
+      // If no specific architecture is selected, include the architecture in the caption
+      // to show which product is actually in the list.
+      bool includeArchitecture = (Architecture == CatalogArchitecture.Any);
+      string caption = includeArchitecture ? product.TitleWithVersionAndArchitecture : product.TitleWithVersion;
+      TreeNode node = new TreeNode(caption);
+      node.ToolTipText = product.Description;
+      node.Tag = product;
+      if (parentNode == null)
+        Nodes.Add(node);
+      else
+        parentNode.Nodes.Add(node);
+    }
+
+    protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
+    {
+      int offset = GetOffset(e.Node);
+      Rectangle cbRect = new Rectangle();
+      cbRect.Location = new Point(offset+10, e.Node.Bounds.Top + ((ItemHeight - CBGlyphSize.Height) / 2));
+      cbRect.Size = CBGlyphSize;
+
+      Rectangle plusMinusRect = new Rectangle();
+      plusMinusRect.Location = new Point(CurrentWidth - 25, 
+        e.Node.Bounds.Top + ((ItemHeight - PlusMinusSize.Height) / 2));
+      plusMinusRect.Size = PlusMinusSize;
+
+      if (cbRect.Contains(e.Location))
+        ClickNode(e.Node);
+      else if (plusMinusRect.Contains(e.Location))
+      {
+        if (e.Node.IsExpanded)
+          e.Node.Collapse();
+        else
+          e.Node.Expand();
+      }
+      base.OnNodeMouseClick(e);
+    }
+
+    private void ClickNode(TreeNode node)
+    {
+      ProductCategory pc = node.Tag as ProductCategory;
+      if (pc != null)
+        ClickCategoryNode(pc);
+      else
+        ClickProductNode(node.Tag as Product);
+    }
+
+    private void ClickCategoryNode(ProductCategory cat)
+    {
+      foreach (Product p in cat.Products)
+      {
+        if (!p.Installed)
+          p.ProposedInstalled = !p.ProposedInstalled;
+
+        List<ProductFeature> productFeatures = p.GetProductFeatures();
+        foreach (ProductFeature pf in productFeatures)
+          pf.ProposedInstalled = p.ProposedInstalled;
+      }
+    }
+
+    private void ClickProductNode(Product p)
+    {
+      if (!p.Installed)
+        p.ProposedInstalled = !p.ProposedInstalled;
+
+      List<ProductFeature> productFeatures = p.GetProductFeatures();
+      foreach (ProductFeature pf in productFeatures)
+        pf.ProposedInstalled = p.ProposedInstalled;
+    }
+
+    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
+    {
+      e.DrawDefault = false;
+      if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0)
+        return;
+
+      CurrentWidth = e.Bounds.Width;
+      DrawBackground(e);
+
+      Rectangle r = e.Bounds;
+      r.Offset(GetOffset(e.Node), 0);
+
+      DrawCheckbox(e, r);
+      if ((e.Node.Tag as ProductCategory) != null && ((e.Node.Tag as ProductCategory).Products.Count > 0))
+        DrawPlusMinus(e, r);
+      DrawState(e, r);
+      DrawText(e, r);
+    }
+
+    private CheckBoxState GetNodeCheckboxState(TreeNode node)
+    {
+      Product product = node.Tag as Product;
+      if (product !=null)
+          return GetStateForProduct(product);
+
+      List<ProductFeature> featureList = new List<ProductFeature>();
+      ProductCategory pc = node.Tag as ProductCategory;
+      foreach (Product p in pc.Products)
+      {
+        List<ProductFeature> productFeatures = p.GetProductFeatures();
+
+        foreach (ProductFeature pf in productFeatures)
+          featureList.Add(pf);
+      }
+      return GetStateFromFeatureList(featureList);
+    }
+
+    private CheckBoxState GetStateForProduct(Product p)
+    {
+      List<ProductFeature> productFeatures = p.GetProductFeatures();
+      CheckBoxState state = GetStateFromFeatureList(productFeatures);
+      if (state == CheckBoxState.CheckedNormal || state == CheckBoxState.MixedNormal)
+      {
+        if (!p.ProposedInstalled)
+          p.ProposedInstalled = true;
+      }
+      if (p.Installed)
+        state = (CheckBoxState)((int)state + 3);
+      return state;
+    }
+
+    private CheckBoxState GetStateFromFeatureList(List<ProductFeature> featureList)
+    {
+      bool allInstalled = true;
+      bool anyInstalled = false;
+      foreach (ProductFeature f in featureList)
+      {
+        allInstalled &= f.ProposedInstalled;
+        anyInstalled |= f.ProposedInstalled;
+      }
+      if (allInstalled)
+        return CheckBoxState.CheckedNormal;
+      if (anyInstalled)
+        return CheckBoxState.MixedNormal;
+
+      return CheckBoxState.UncheckedNormal;
+    }
+
+    private int GetOffset(TreeNode node)
+    {
+      return node.Level * 15;
+    }
+
+    private Image GetNodeIcon(TreeNode node)
+    {
+      while (node != null)
+      {
+        ProductCategory pc = node.Tag as ProductCategory;
+        if (pc != null)
+          return pc.SmallIcon;
+        Product p = node.Tag as Product;
+        if (p.SmallIcon != null)
+          return p.SmallIcon;
+        node = node.Parent;
+      }
+      return null;
+    }
+
+    private void DrawCheckbox(DrawTreeNodeEventArgs e, Rectangle r)
+    {
+      CheckBoxState state = GetNodeCheckboxState(e.Node);
+
+      if (CBGlyphSize.IsEmpty)
+        CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
+      int offset = (ItemHeight - CBGlyphSize.Height) / 2;
+      Point location = new Point(r.Left+10, r.Top + offset);
+
+      CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
+    }
+
+    private void DrawPlusMinus(DrawTreeNodeEventArgs e, Rectangle r)
+    {
+      Image displayImage = (e.Node.IsExpanded) ? Resources.minus_sign : Resources.plus_sign;
+      if (PlusMinusSize.IsEmpty)
+        PlusMinusSize = displayImage.Size;
+      int top = r.Top + ((ItemHeight - displayImage.Height) / 2);
+      int left = r.Left + r.Width - 25;
+
+      e.Graphics.DrawImageUnscaled(displayImage, left, top);
+    }
+
+    private void DrawText(DrawTreeNodeEventArgs e, Rectangle r)
+    {
+      bool drawActive = ((e.State & TreeNodeStates.Selected) != 0) && Focused;
+      Brush brush = drawActive ? Brushes.White : Brushes.Black;
+
+      Rectangle textBounds = new Rectangle(r.Left + 62, r.Top, r.Width, r.Height);
+      StringFormat format = new StringFormat(StringFormatFlags.NoWrap);
+      format.LineAlignment = StringAlignment.Center;
+      format.Trimming = StringTrimming.EllipsisCharacter;
+      e.Graphics.DrawString(e.Node.Text, Font, brush, textBounds, format);
+    }
+
+    private void DrawState(DrawTreeNodeEventArgs e, Rectangle r)
+    {
+      int top = r.Top;
+      int left = r.Left;
+
+      Image icon = GetNodeIcon(e.Node);
+      if (icon != null)
+        e.Graphics.DrawImage(icon, left + 32, top + 6);
+
+      //ProductCategory pc = e.Node.Tag as ProductCategory;
+      //int index = -1;
+      // if (pc == null)
+      //{
+        //  ProductFeature f = e.Node.Tag as ProductFeature;
 //                if ((!f.Installed && !f.ProposedInstalled))
-  //                  DisableImage(b);
-    //            if (f.Installed != f.ProposedInstalled)
-      //              index = f.Installed ? 1 : 0;
-            //}
-
-        //    if (index >= 0)
-          //      StateImageList.Draw(e.Graphics, left+44, top+20, index);
-        }
-
-        private void DrawBackground(DrawTreeNodeEventArgs e)
-        {
-            Color c = BackColor;
-            if (e.Node.IsSelected)
-                c = Color.LightGray;
-
-            using (Brush backBrush = new SolidBrush(c))
-            {
-                e.Graphics.FillRectangle(backBrush, e.Bounds);
-            }
-        }
-
-        private void PartiallyDisableImage(Bitmap b)
-        {
-            int width = b.Width;
-            for (int y = 0; y < b.Height; y++)
-            {
-                for (int x = 0; x < width; x++)
-                {
-                    Color c = b.GetPixel(x, y);
-                    int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
-                    b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
-                }
-                width--;
-            }
-        }
-
-        private void DisableImage(Bitmap b)
-        {
-            for (int y = 0; y < b.Height; y++)
-                for (int x = 0; x < b.Width; x++)
-                {
-                    Color c = b.GetPixel(x, y);
-                    int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
-                    b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
-                }
-        }
-
-        private void InitializeComponent()
-        {
-            this.SuspendLayout();
-            // 
-            // FeatureTreeView
-            // 
-            this.Font = new System.Drawing.Font("Tahoma", 8.25F);
-            this.ResumeLayout(false);
-
-        }
-    }
+//                  DisableImage(b);
+//            if (f.Installed != f.ProposedInstalled)
+//              index = f.Installed ? 1 : 0;
+      //}
+
+  //    if (index >= 0)
+    //      StateImageList.Draw(e.Graphics, left+44, top+20, index);
+    }
+
+    /// <summary>
+    /// Draws a custom background.
+    /// </summary>
+    private void DrawBackground(DrawTreeNodeEventArgs e)
+    {
+      Brush brush;
+      if ((e.State & TreeNodeStates.Selected) != 0)
+      {
+        if (Focused)
+          brush = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
+        else
+          brush = new SolidBrush(Color.LightGray);
+      }
+      else
+        brush = new SolidBrush(BackColor);

+
+      e.Graphics.FillRectangle(brush, e.Bounds);
+      brush.Dispose();
+    }
+
+    private void PartiallyDisableImage(Bitmap b)
+    {
+      // TODO: use a color matrix operation for that type of manipulation instead.
+      int width = b.Width;
+      for (int y = 0; y < b.Height; y++)
+      {
+        for (int x = 0; x < width; x++)
+        {
+          Color c = b.GetPixel(x, y);
+          int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
+          b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
+        }
+        width--;
+      }
+    }
+
+    private void DisableImage(Bitmap b)
+    {
+      // TODO: use a color matrix operation for that type of manipulation instead.
+      for (int y = 0; y < b.Height; y++)
+        for (int x = 0; x < b.Width; x++)
+        {
+          Color c = b.GetPixel(x, y);
+          int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
+          b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
+        }
+    }
+
+    private void InitializeComponent()
+    {
+      this.SuspendLayout();
+      // 
+      // FeatureTreeView
+      // 
+      this.CausesValidation = false;
+      this.Font = new System.Drawing.Font("Tahoma", 8.25F);
+      this.FullRowSelect = true;
+      this.HideSelection = false;
+      this.ShowLines = false;
+      this.ShowPlusMinus = false;
+      this.ShowRootLines = false;
+      this.ResumeLayout(false);
+
+    }
+  }
 }

=== added file 'WexInstaller/Controls/FeatureTreeView.resx'
--- a/WexInstaller/Controls/FeatureTreeView.resx	1970-01-01 00:00:00 +0000
+++ b/WexInstaller/Controls/FeatureTreeView.resx	2011-03-18 10:29:04 +0000
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+</root>
\ No newline at end of file

=== modified file 'WexInstaller/InstallWizard/Features.Designer.cs'
--- a/WexInstaller/InstallWizard/Features.Designer.cs	2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.Designer.cs	2011-03-18 10:29:04 +0000
@@ -37,6 +37,9 @@
           this.pictureBox2 = new System.Windows.Forms.PictureBox();
           this.label1 = new System.Windows.Forms.Label();
           this.catalogImageList = new System.Windows.Forms.ImageList(this.components);
+          this.architectureCombobox = new System.Windows.Forms.ComboBox();
+          this.featureToolTip = new System.Windows.Forms.ToolTip(this.components);
+          this.architectureLabel = new System.Windows.Forms.Label();
           this.featureTree = new WexInstaller.Controls.FeatureTreeView();
           this.featureBox = new WexInstaller.Controls.FeatureBox();
           this.driveSpace = new WexInstaller.Controls.DriveSpaceControl();
@@ -71,10 +74,10 @@
           this.catalogList.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
           this.catalogList.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
           this.catalogList.FormattingEnabled = true;
-          this.catalogList.ItemHeight = 20;
+          this.catalogList.ItemHeight = 18;
           this.catalogList.Location = new System.Drawing.Point(53, 125);
           this.catalogList.Name = "catalogList";
-          this.catalogList.Size = new System.Drawing.Size(493, 26);
+          this.catalogList.Size = new System.Drawing.Size(397, 24);
           this.catalogList.TabIndex = 13;
           this.catalogList.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.catalogList_DrawItem);
           this.catalogList.SelectedIndexChanged += new System.EventHandler(this.catalogList_SelectedIndexChanged);
@@ -108,6 +111,35 @@
           this.catalogImageList.Images.SetKeyName(2, "MySQLInstallerProductCatalog_InPackage.png");
           this.catalogImageList.Images.SetKeyName(3, "MySQLInstallerProductCatalog_OnDisk.png");
           // 
+          // architectureCombobox
+          // 
+          this.architectureCombobox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+          this.architectureCombobox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+          this.architectureCombobox.Font = new System.Drawing.Font("Tahoma", 9.75F);
+          this.architectureCombobox.FormattingEnabled = true;
+          this.architectureCombobox.ItemHeight = 16;
+          this.architectureCombobox.Items.AddRange(new object[] {
+            "32-Bit",
+            "64-Bit",
+            "Any"});
+          this.architectureCombobox.Location = new System.Drawing.Point(456, 125);
+          this.architectureCombobox.Name = "architectureCombobox";
+          this.architectureCombobox.Size = new System.Drawing.Size(90, 24);
+          this.architectureCombobox.TabIndex = 16;
+          this.featureToolTip.SetToolTip(this.architectureCombobox, "Only products of the selected architecture type will be shown in the list below.");
+          this.architectureCombobox.SelectedIndexChanged += new System.EventHandler(this.architectureCombobox_SelectedIndexChanged);
+          // 
+          // architectureLabel
+          // 
+          this.architectureLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+          this.architectureLabel.AutoSize = true;
+          this.architectureLabel.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+          this.architectureLabel.Location = new System.Drawing.Point(453, 108);
+          this.architectureLabel.Name = "architectureLabel";
+          this.architectureLabel.Size = new System.Drawing.Size(79, 14);
+          this.architectureLabel.TabIndex = 17;
+          this.architectureLabel.Text = "Architecture:";
+          // 
           // featureTree
           // 
           this.featureTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
@@ -118,6 +150,7 @@
           this.featureTree.DrawMode = System.Windows.Forms.TreeViewDrawMode.OwnerDrawAll;
           this.featureTree.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
           this.featureTree.FullRowSelect = true;
+          this.featureTree.HideSelection = false;
           this.featureTree.ImageIndex = 0;
           this.featureTree.ImageList = this.imageList1;
           this.featureTree.ItemHeight = 40;
@@ -130,7 +163,7 @@
           this.featureTree.Size = new System.Drawing.Size(279, 256);
           this.featureTree.TabIndex = 12;
           this.featureTree.BeforeCheck += new System.Windows.Forms.TreeViewCancelEventHandler(this.featureTree_BeforeCheck);
-          this.featureTree.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.featureTree_NodeMouseClick);
+          this.featureTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.featureTree_AfterSelect);
           // 
           // featureBox
           // 
@@ -161,6 +194,8 @@
           this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
           this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
           this.BackColor = System.Drawing.SystemColors.Window;
+          this.Controls.Add(this.architectureLabel);
+          this.Controls.Add(this.architectureCombobox);
           this.Controls.Add(this.label1);
           this.Controls.Add(this.pictureBox2);
           this.Controls.Add(this.catalogList);
@@ -180,6 +215,8 @@
           this.Controls.SetChildIndex(this.catalogList, 0);
           this.Controls.SetChildIndex(this.pictureBox2, 0);
           this.Controls.SetChildIndex(this.label1, 0);
+          this.Controls.SetChildIndex(this.architectureCombobox, 0);
+          this.Controls.SetChildIndex(this.architectureLabel, 0);
           ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
           this.ResumeLayout(false);
           this.PerformLayout();
@@ -197,5 +234,8 @@
         private System.Windows.Forms.PictureBox pictureBox2;
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.ImageList catalogImageList;
+        private System.Windows.Forms.ComboBox architectureCombobox;
+        private System.Windows.Forms.ToolTip featureToolTip;
+        private System.Windows.Forms.Label architectureLabel;
     }
 }

=== modified file 'WexInstaller/InstallWizard/Features.cs'
--- a/WexInstaller/InstallWizard/Features.cs	2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.cs	2011-03-18 10:29:04 +0000
@@ -7,39 +7,226 @@
 using WexInstaller.Core;
 using WexInstaller.Properties;
 
+using MySQL.Utilities.SysUtils;
+
 namespace WexInstaller
 {
   public partial class FeatureSelection : InstallerPanel
   {
+
+    #region Members and constants
+
+    // This class represents a line in the catalog drop down.  The state item indicates the download
+    // state of the products
+    private class CatalogState
+    {
+      public const int ProductsDownload = 0;
+      public const int ProductsDownloadCommercial = 1;
+      public const int ProductsInCache = 2;
+      public const int InstalledProducts = 3;
+
+      public int DownloadState;
+      public string Text;
+      public ProductCatalog catalog;
+
+      public CatalogState(ProductCatalog catalog)
+      {
+        this.catalog = catalog;
+        Text = catalog.Description;
+        DownloadState = ProductsInCache;
+        DownloadState = GetCatalogDownloadState(catalog);
+      }
+
+      public CatalogState(string text, bool isAllProducts)
+      {
+        catalog = null;
+        Text = text;
+        DownloadState = ProductsInCache;
+        DownloadState = isAllProducts ? GetAllDownloadState() : InstalledProducts;
+      }
+
+      public bool NeedsDownload
+      {
+        get
+        {
+          return DownloadState == ProductsDownload || DownloadState == ProductsDownloadCommercial;
+        }
+      }
+
+      public string SubText
+      {
+        get
+        {
+          if (DownloadState == ProductsInCache)
+            return Resources.PackagesAvailable;
+          if (DownloadState == InstalledProducts)
+            return Resources.PackagesAlreadyInstalled;
+          if (DownloadState == ProductsDownloadCommercial)
+            return Resources.PackagesAvailableForCommercialDownload;
+          return Resources.PackagesAvailableForDownload;
+        }
+      }
+
+      public int GetCatalogDownloadState(ProductCatalog catalog)
+      {
+        int index = ProductsInCache;
+        foreach (CatalogProduct cp in catalog.Products)
+          if (!cp.ReferencedProduct.FoundLocal)
+          {
+            index = ProductsDownload;
+            break;
+          }
+        if (catalog.Commercial && index == ProductsDownload)
+          index = ProductsDownloadCommercial;
+        return index;
+      }
+
+      public int GetAllDownloadState()
+      {
+        int index = ProductsInCache;
+        foreach (ProductCategory cat in ProductManager.ProductCategories)
+          foreach (Product p in cat.Products)
+            if (!p.FoundLocal)
+              index = ProductsDownload;
+        return index;
+      }
+    }
+
+    #endregion
+
+    #region Construction and setup
+
     public FeatureSelection()
     {
       InitializeComponent();
       Caption = "Feature Selection";
       featureBox.FeatureTree = featureTree;
+
+      // Hide the architecture selection box if we are on a 32 OS.
+      architectureCombobox.SelectedIndex = 0;
+      if (!Win32.Is64BitOS())
+      {
+        architectureCombobox.Visible = false;
+        architectureLabel.Visible = false;
+        catalogList.Width = featureBox.Right - catalogList.Left;
+      }
     }
+    
+    #endregion
+
+    #region Application logic
 
     public override void Activate()
     {
-      // Load our catalog dropdown. Keep the last selected entry for re-selection.
-      // We cannot use the active catalog here as not all entries have a catalog counterpart.
+      // Load the catalog dropdown. Display only one catalog per architecture and use the
+      // architectureCombobox to let the user select the architecture instead.
+      string currentCatalogName = "";
+      if (ProductManager.ActiveCatalog != null)
+      {
+        currentCatalogName = ProductManager.ActiveCatalog.Name;
+        if (ProductManager.ActiveCatalog.Requires64BitArchitecture)
+          architectureCombobox.SelectedIndex = 1;
+      }
+
       int selectedIndex = catalogList.SelectedIndex;
-      if (selectedIndex < 0)
-        selectedIndex = 0;
       catalogList.Items.Clear();
 
       foreach (ProductCatalog catalog in ProductManager.Catalogs)
-        catalogList.Items.Add(new CatalogState(catalog));
+        if (!catalog.Requires64BitArchitecture)
+        {
+          catalogList.Items.Add(new CatalogState(catalog));
+          if (selectedIndex == -1 && catalog.Name == currentCatalogName)
+            selectedIndex = catalogList.Items.Count - 1;
+        }
 
+      // These special "catalogs" are available for any architecture.
       catalogList.Items.Add(new CatalogState(Resources.AllMySQLProducts, true));
       catalogList.Items.Add(new CatalogState(Resources.InstalledMySQLProducts, false));
 
-      catalogList.SelectedIndex = selectedIndex;
+      if (selectedIndex > -1)
+        catalogList.SelectedIndex = selectedIndex;
+      else
+        catalogList.SelectedIndex = 0;
+      catalogList.Focus();
 
       NextButton.Text = Properties.Resources.NextButtonDefaultText;
       base.Activate();
     }
 
-    private void featureTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
+    /// <summary>
+    /// Called when either the catalog or the architecture was changed by the user.
+    /// Updates the list of displayed products and their features.
+    /// </summary>
+    private void UpdateFeatureDisplay()
+    {
+      if (catalogList.SelectedIndex < 0)
+        return;
+
+      ProductCatalog catalog = null;
+      bool installedItems = catalogList.SelectedIndex == (catalogList.Items.Count - 1);
+      bool allProducts = catalogList.SelectedIndex == (catalogList.Items.Count - 2);
+      CatalogArchitecture architecture;
+      switch (architectureCombobox.SelectedIndex)
+      {
+        case 0:
+          architecture = CatalogArchitecture.X86;
+          break;
+        case 1:
+          architecture = CatalogArchitecture.X64;
+          break;
+        default:
+          architecture = CatalogArchitecture.Any;
+          break;
+      }
+
+      CatalogState state = catalogList.Items[catalogList.SelectedIndex] as CatalogState;
+      catalog = state.catalog;
+
+      FillFeatureTree(architecture, allProducts, installedItems, catalog);
+
+      if (featureTree.Nodes.Count > 0)
+      {
+        featureTree.SelectedNode = featureTree.Nodes[0];
+        featureBox.SelectedObject = featureTree.SelectedNode.Tag as ProductElement;
+      }
+      else
+        featureBox.SelectedObject = null;
+      driveSpace.Calculate();
+    }
+
+    /// <summary>
+    /// Responsible to set up the feature tree based on the given selection.
+    /// </summary>
+    /// <param name="architecture">The architecture to consider for each product.</param>
+    /// <param name="allProducts">True, if all products should be added (filtered by arch).</param>
+    /// <param name="installedItems">True, if already installed products should be added (filtered by arch).</param>
+    /// <param name="catalog">The catalog carrying the products to show if neither allProducts nor installedItems are true.
+    /// Also subject to the given architecture.</param>
+    private void FillFeatureTree(CatalogArchitecture architecture, bool allProducts, bool installedItems, ProductCatalog catalog)
+    {
+      featureTree.Nodes.Clear();
+      featureTree.Architecture = architecture;
+      featureBox.Catalog = catalog;
+      featureBox.ListAllItems = allProducts;
+      featureBox.ListInstalledItems = installedItems;
+
+      foreach (ProductCategory pc in ProductManager.ProductCategories)
+      {
+        List<Product> products = featureBox.GetProducts(pc);
+
+        TreeNode node = null;
+        if (products.Count > 1)
+          node = featureTree.AddCategory(pc);
+        foreach (Product p in products)
+          featureTree.AddProduct(p, node);
+      }
+    }
+
+    #endregion
+
+    #region Event handling
+
+    private void featureTree_AfterSelect(object sender, TreeViewEventArgs e)
     {
       featureBox.SelectedObject = e.Node.Tag as ProductElement;
     }
@@ -48,7 +235,7 @@
     {
       FeatureTreeView ftv = sender as FeatureTreeView;
       if (ftv != null)
-          ftv.SelectedNode = e.Node;
+        ftv.SelectedNode = e.Node;
     }
 
     private void catalogList_DrawItem(object sender, DrawItemEventArgs e)
@@ -80,128 +267,49 @@
 
     private void catalogList_SelectedIndexChanged(object sender, EventArgs e)
     {
-      // Keep track of the active catalog an refill the feature tree.
-      if (catalogList.SelectedIndex < ProductManager.Catalogs.Count)
-        ProductManager.ActiveCatalog = ProductManager.Catalogs[catalogList.SelectedIndex];
-      else
+      // Keep track of the active catalog and refill the feature tree.
+      // Architecture selection is not possible with the two "virtual" categories,
+      // namely "All products" and "All installed products".
+      CatalogState state = catalogList.Items[catalogList.SelectedIndex] as CatalogState;
+
+      if (state.catalog == null)
         ProductManager.ActiveCatalog = null;
-      featureTree.Nodes.Clear();
-
-      ProductCatalog catalog = null;
-      bool installedItems = catalogList.SelectedIndex == (catalogList.Items.Count - 1);
-      bool allProducts = catalogList.SelectedIndex == (catalogList.Items.Count - 2);
-      if (!installedItems && !allProducts)
-        catalog = ProductManager.Catalogs[catalogList.SelectedIndex];
-
-      foreach (ProductCategory pc in ProductManager.ProductCategories)
-      {
-        List<Product> products = new List<Product>();
-        foreach (Product p in pc.Products)
-        {
-          if (allProducts || installedItems)
-          {
-            if (allProducts || p.Installed)
-              products.Add(p);
-          }
-          else
-          {
-            foreach (CatalogProduct cp in catalog.Products)
-              if (String.Compare(cp.ProductId, p.Name, true) == 0)
-                products.Add(p);
-          }
-        }
-        if (products.Count == 1)
-          featureTree.AddProduct(products[0], null);
-        else
-          if (products.Count > 1)
-          {
-            TreeNode node = featureTree.AddCategory(pc);
-            foreach (Product p in products)
-              featureTree.AddProduct(p, node);
-          }
-      }
-
-      if (featureTree.Nodes.Count > 0)
-      {
-        featureTree.SelectedNode = featureTree.Nodes[0];
-        featureBox.SelectedObject = featureTree.SelectedNode.Tag as ProductElement;
-      }
       else
-        featureBox.SelectedObject = null;
-      driveSpace.Calculate();
-    }
-  }
-
-  // This class represents a line in the catalog drop down.  The state item indicates the download
-  // state of the products
-  class CatalogState
-  {
-    public const int ProductsDownload = 0;
-    public const int ProductsDownloadCommercial = 1;
-    public const int ProductsInCache = 2;
-    public const int InstalledProducts = 3;
-
-    public int DownloadState;
-    public string Text;
-
-    public CatalogState(ProductCatalog catalog)
-    {
-      Text = catalog.Description;
-      DownloadState = ProductsInCache;
-      DownloadState = GetCatalogDownloadState(catalog);
-    }
-
-    public CatalogState(string text, bool isAllProducts)
-    {
-      Text = text;
-      DownloadState = ProductsInCache;
-      DownloadState = isAllProducts ? GetAllDownloadState() : InstalledProducts;
-    }
-
-    public bool NeedsDownload
-    {
-      get
-      {
-        return DownloadState == ProductsDownload || DownloadState == ProductsDownloadCommercial;
-      }
-    }
-
-    public string SubText
-    {
-      get
-      {
-        if (DownloadState == ProductsInCache)
-          return Resources.PackagesAvailable;
-        if (DownloadState == InstalledProducts)
-          return Resources.PackagesAlreadyInstalled;
-        if (DownloadState == ProductsDownloadCommercial)
-          return Resources.PackagesAvailableForCommercialDownload;
-        return Resources.PackagesAvailableForDownload;
-      }
-    }
-
-    public int GetCatalogDownloadState(ProductCatalog catalog)
-    {
-      int index = ProductsInCache;
-      foreach (CatalogProduct cp in catalog.Products)
-        if (!cp.ReferencedProduct.FoundLocal)
+      {
+        // Even though the catalog in the catalog list carries an architecture it is not
+        // meant to be used for selection of an architecture (the architectureCombobox is).
+        // So find the catalog with the same name as currently selected in the catalog list
+        // and combine this with the selected architecture to find the real catalog.
+        bool use64Bit;
+        switch (architectureCombobox.SelectedIndex)
         {
-            index = ProductsDownload;
+          case 0:
+            use64Bit = false;
+            break;
+          case 1:
+            use64Bit = true;
+            break;
+          default:
+            use64Bit = Win32.Is64BitOS();
             break;
         }
-      if (catalog.Commercial && index == ProductsDownload)
-        index = ProductsDownloadCommercial;
-      return index;
+
+        foreach (ProductCatalog catalog in ProductManager.Catalogs)
+          if (catalog.Requires64BitArchitecture == use64Bit && catalog.Name == state.catalog.Name)
+          {
+            ProductManager.ActiveCatalog = catalog;
+            break;
+          }
+      }
+      UpdateFeatureDisplay();
     }
 
-    public int GetAllDownloadState()
+    private void architectureCombobox_SelectedIndexChanged(object sender, EventArgs e)
     {
-      int index = ProductsInCache;
-      foreach (ProductCategory cat in ProductManager.ProductCategories)
-        foreach (Product p in cat.Products)
-          if (!p.FoundLocal)
-            index = ProductsDownload;
-      return index;
+      UpdateFeatureDisplay();
     }
+
+    #endregion
+
   }
 }

=== modified file 'WexInstaller/InstallWizard/Features.resx'
--- a/WexInstaller/InstallWizard/Features.resx	2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.resx	2011-03-18 10:29:04 +0000
@@ -125,7 +125,7 @@
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA4
-        KAAAAk1TRnQBSQFMAgEBBAEAARgBAAEYAQABGAEAARgBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFg
+        KAAAAk1TRnQBSQFMAgEBBAEAAWgBAAFoAQABGAEAARgBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFg
         AwABMAMAAQEBAAEgBgABSP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
         /wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ADYAA+oB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
         AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
@@ -137,165 +137,165 @@
         Af8BzAKZAf8BzAKZAf8BzAKZAf8BzAKZAf8DzAH/A+oB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
         AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
         AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wPMAf8BzAKZAf8BzAGZ
-        ATAB/wLMAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAWMB/wHMAZkBMAH/AcwCmQH/AcwBmQEwAf8CzAFjAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
-        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
-        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAFjAf8BzAGZATAB/wGkAqAB/wHMAZkBMAH/
-        AswBYwH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBYwH/AcwBmQEwAf8CzAFjAf8CzAGZ
-        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
-        Af8CzAFjAf8CmQEwAf8CzAGZAf8BzAGZATAB/wLMAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAZkB/wLMAZkB/wLMAWMB/wLMAWMB/wLMAWMB/wHMAZkBMAH/ApkBYwH/AswBYwL/AewBzAH/
+        ASYB/wLMAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AZkB/wLMAVkB/wHMAZkBJgH/AcwCmQH/AcwBmQEmAf8CzAFZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAFZAf8BzAGZASYB/wGkAqAB/wHMAZkBJgH/
+        AswBWQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBWQH/AcwBmQEmAf8CzAFZAf8CzAGZ
+        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+        Af8CzAFZAf8CmQEmAf8CzAGZAf8BzAGZASYB/wLMAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AZkB/wLMAZkB/wLMAZkB/wLMAVkB/wLMAVkB/wLMAVkB/wHMAZkBJgH/ApkBWQH/AswBWQL/AewBzAH/
         AfABygGmAf8D6gH/AfABygGmAv8B7AHMAf8D6gX/AfABygGmBf8B8AHKAaYB/wPqAf8D6iL/AewBzAH/
-        AcwBmQEwAf8CmQFjAf8CzAFjBf8B8AHKAaYC/wHsAcwB/wHwAcoBpgL/AewBzAH/A/EC/wHsAcwB/wPq
+        AcwBmQEmAf8CmQFZAf8CzAFZBf8B8AHKAaYC/wHsAcwB/wHwAcoBpgL/AewBzAH/A/EC/wHsAcwB/wPq
         Av8B7AHMAf8D8QL/AewBzAL/AewBzAH/A+oB/wHwAcoBpgH/A/EC/wHsAcwC/wHsAcwB/wHwAcoBpgL/
-        AewBzAb/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D6gn/A/EC/wHsAcwB/wHwAcoBpgL/AewBzAH/
-        AcwBmQFjAf8B8AHKAaYB/wPqAv8B7AHMAf8D6iL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D6gH/
+        AewBzAb/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D6gn/A/EC/wHsAcwB/wHwAcoBpgL/AewBzAH/
+        AcwBmQFZAf8B8AHKAaYB/wPqAv8B7AHMAf8D6iL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D6gH/
         AfABygGmAf8D6gL/AewBzAH/AfABygGmAf8D8QH/AfABygGmAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wPq
-        Af8B8AHKAaYC/wHsAcwB/wPqAf8D6gH/AfABygGmAv8B7AHMAf8D8QH/AfABygGmAf8CzAFjAv8B7AHM
-        Af8BzAGZATAB/wKZAWMB/wLMAWMC/wHsAcwB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMC/wHs
-        AcwB/wHMAZkBMAH/AswBYwH/AswBYwH/AswBmQH/AswBYwH/A/Ee/wHsAcwB/wHMAZkBMAH/ApkBYwH/
-        AswBYwH/AswBmQH/AfABygGmAf8B8AHKAaYB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAZkB/wLM
-        AWMB/wLMAZkB/wHMAZkBMAH/AswBYwH/AswBYwH/AfABygGmAf8B8AHKAaYB/wHwAcoBpgH/AswBYwH/
-        AswBYwH/AswBYwH/AfABygGmAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wLMAZkB/wLMAWMB/wHw
-        AcoBpgH/AswBmQH/AswBYwH/AswBYwH/AswBYwH/AswBmQH/AswBYwH/AswBmQH/AswBYwH/AswBmQL/
-        AewBzB7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8CzAGZAf8B8AHKAaYB/wLMAWMB/wLMAWMB/wLM
-        AWMB/wLMAWMB/wHwAcoBpgH/AswBYwH/AfABygGmAf8CzAGZAf8CzAFjAf8CzAFjAf8CzAFjAf8CzAFj
-        Af8B8AHKAaYB/wHMAZkBMAH/AswBYwH/AswBmQH/AfABygGmAf8CzAFjAv8B7AHMAf8BzAGZAWMB/wKZ
-        AWMB/wLMAWMB/wHwAcoBpgH/AswBYwL/AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/
-        AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAf8D8R7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8B8AHK
+        Af8B8AHKAaYC/wHsAcwB/wPqAf8D6gH/AfABygGmAv8B7AHMAf8D8QH/AfABygGmAf8CzAFZAv8B7AHM
+        Af8BzAGZASYB/wKZAVkB/wLMAVkC/wHsAcwB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkC/wHs
+        AcwB/wHMAZkBJgH/AswBWQH/AswBWQH/AswBmQH/AswBWQH/A/Ee/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+        AswBWQH/AswBmQH/AfABygGmAf8B8AHKAaYB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAZkB/wLM
+        AVkB/wLMAZkB/wHMAZkBJgH/AswBWQH/AswBWQH/AfABygGmAf8B8AHKAaYB/wHwAcoBpgH/AswBWQH/
+        AswBWQH/AswBWQH/AfABygGmAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wLMAZkB/wLMAVkB/wHw
+        AcoBpgH/AswBmQH/AswBWQH/AswBWQH/AswBWQH/AswBmQH/AswBWQH/AswBmQH/AswBWQH/AswBmQL/
+        AewBzB7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8CzAGZAf8B8AHKAaYB/wLMAVkB/wLMAVkB/wLM
+        AVkB/wLMAVkB/wHwAcoBpgH/AswBWQH/AfABygGmAf8CzAGZAf8CzAFZAf8CzAFZAf8CzAFZAf8CzAFZ
+        Af8B8AHKAaYB/wHMAZkBJgH/AswBWQH/AswBmQH/AfABygGmAf8CzAFZAv8B7AHMAf8BzAGZAVkB/wKZ
+        AVkB/wLMAVkB/wHwAcoBpgH/AswBWQL/AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/
+        AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAf8D8R7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8B8AHK
         AaYB/wLMAZkC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxAf8B8AHKAaYC/wHsAcwC/wHs
         AcwC/wHsAcwC/wHsAcwC/wHsAcwB/wHwAcoBpgH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8B8AHK
-        AaYC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAFjAf8CzAFjAf8B8AHKAaYC/wHs
+        AaYC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAFZAf8CzAFZAf8B8AHKAaYC/wHs
         AcwB/wPqAv8B7AHMAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/AfABygGmAv8B7AHMIv8B7AHMAf8BzAGZ
-        ATAB/wKZAWMB/wLMAWMB/wHwAcoBpgH/AswBYwH/AswBmQL/AewBzAL/AewBzAL/AewBzAL/AewBzAH/
-        AswBYwL/AewBzAH/AfABygGmAf8CzAGZAf8CzAGZAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wHwAcoBpgH/
-        A+oB/wHwAcoBpgL/AewBzAL/AewBzAL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QL/AewBzAL/
-        AewBzAH/AfABygGmAf8BzAP/AcwD/wHGAdYB7wH/AcwD/wHWAucu/wHsAcwB/wHMAZkBMAH/ApkBYwH/
-        AswBYwX/A+MC/wHsAcwB/wHwAcoBpgH/AcwD/wHMA/8BxgHWAe8B/wHMA/8BzDD/AewBzAH/AcwBmQEw
-        Af8CmQFjAf8CzAFjAf8D8QH/A+MB/wPjAf8B8AHKAaYB/wHMA/8BzAP/AcYB1gHvAf8BzAP/AdYC5wH/
-        A/Eq/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EB/wPjAv8B7AHMAf8B8AHKAaYB/wHMA/8BzAP/
-        AcYB1gHvAf8B1gLnAf8BzAP/A/Eq/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAGZ
+        ASYB/wKZAVkB/wLMAVkB/wHwAcoBpgH/AswBWQH/AswBmQL/AewBzAL/AewBzAL/AewBzAL/AewBzAH/
+        AswBWQL/AewBzAH/AfABygGmAf8CzAGZAf8CzAGZAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wHwAcoBpgH/
+        A+oB/wHwAcoBpgL/AewBzAL/AewBzAL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QL/AewBzAL/
+        AewBzAH/AfABygGmAf8BzAP/AcwD/wHGAdYB7wH/AcwD/wHWAucu/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+        AswBWQX/A+MC/wHsAcwB/wHwAcoBpgH/AcwD/wHMA/8BxgHWAe8B/wHMA/8BzDD/AewBzAH/AcwBmQEm
+        Af8CmQFZAf8CzAFZAf8D8QH/A+MB/wPjAf8B8AHKAaYB/wHMA/8BzAP/AcYB1gHvAf8BzAP/AdYC5wH/
+        A/Eq/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EB/wPjAv8B7AHMAf8B8AHKAaYB/wHMA/8BzAP/
+        AcYB1gHvAf8B1gLnAf8BzAP/A/Eq/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAGZ
         Af8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7Hv8D8QL/AewBzAr/AewBzAH/
-        AcwBmQEwAf8CmQFjAf8CzAFjAf8B8AHKAaYB/wLMAZkB/wLMAZkB/wPXAf8BmQHMAv8BmQHMAv8BmQHM
-        Av8BxgHWAe8B/wHwAfsv/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAGZAf8CzAGZ
-        Af8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7L/8B7AHMAf8BzAGZATAB/wHMAZkBYwH/
-        AswBYwH/AfABygGmAf8CzAGZAf8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7
-        L/8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfse/wHwAcoBpgH/
-        AfABygGmAf8D8Qr/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7
-        M/8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfsz/wHsAcwB/wHM
-        AZkBMAH/AcwBmQFjAf8CzAFjEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7M/8B7AHMAf8BzAGZATAB/wKZ
-        AWMC/wHMAWM5/wHwAcoBpgH/AfABygGmEv8B7AHMAf8BzAGZATAB/wKZAWMC/wHMAWNS/wHsAcwB/wHM
-        AZkBMAH/ApkBYwL/AcwBYxn/A90B/wHwAcoBpgH/AfABygGmAf8D6gX/A9cB/wPdAf8D6hr/AewBzAH/
-        AcwBmQEwAf8BzAGZAWMC/wHMAWMJ/wPxAv8B7AHMAf8D6hH/A/EC/wHsAcwB/wPxEf8D6gL/AewBzAH/
-        A/EG/wHsAcwB/wHMAZkBMAH/AcwBmQFjAv8BzAFjIv8B7AHMAf8D8RL/AewBzAH/AfABygGmAf8CzAGZ
-        Af8D6gr/AewBzAH/AcwBmQEwAf8BzAGZAWMC/wHMAWMB/wPxAf8D8Sn/A/EC/wHsAcwC/wHsAcwC/wHs
-        AcwC/wHsAcwB/wPxCv8B7AHMAf8BzAGZATAB/wKZAWMC/wHMAWMV/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AWMC/wHsAcwB/wPqAf8CzAFjAf8CzAGZAf8CzAGZAf8CzAGZAf8D6hL/AewBzAH/AcwBmQEwAf8BzAGZ
-        AWMC/wHMAWMK/wHsAcwB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wLMAZkB/wPjAf8D4wH/AswBmQH/
-        AcwBmQEwAf8CzAFjAf8D4wH/A+MB/wLMAZkB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMC/wHsAcwG/wHs
-        AcwB/wHMAZkBMAH/ApkBYwL/AcwBYxX/AfABygGmAf8B8AHKAaYB/wHwAcoBpgL/AewBzBX/A+MB/wHw
-        AcoBpgL/AewBzA7/AewBzAH/AcwBmQEwAf8CmQFjAv8BzAFjAf8B8AHKAaYB/wLMAZkB/wHwAcoBpiL/
-        AewBzAH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBYwH/AfABygGmAv8B7AHMAf8D6gL/AewBzAH/
-        AcwBmQEwAf8CmQFjAv8BzAFjFf8CzAGZAf8CzAFjAf8CzAFjAf8CzAFjAf8D4wX/AswBYwH/AswBYwH/
-        AswBYwH/AswBYwH/A+MS/wHsAcwB/wHMAZkBMAH/AcwBmQFjAv8BzAFjDv8B7AHMAf8B8AHKAaYB/wHM
-        AZkBYwH/AZkBYwEwAf8BmQFjATAB/wKZATAB/wGZAWMBMAH/AcwBmQFjAf8BmQFjATAB/wGZAWMBMAH/
-        AZkBYwEwAf8BmQFjATAB/wHMAZkBYwH/AfABygGmAv8B7AHMCv8B7AHMAf8BzAGZATAB/wKZAWMC/wHM
-        AWMR/wPqAf8CzAGZAf8BzAGZAWMB/wLMAZkR/wPxAf8BzAGZAWMB/wLMAZkB/wPxEv8B7AHMAf8BzAGZ
-        ATAB/wKZAWMC/wHMAWMB/wPqAf8B8AHKAaYB/wHMAZkBYwH/A90Z/wPxAf8CzAFjAf8BzAGZAWMB/wHM
-        AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwL/AewBzAH/
-        AcwBmQEwAf8CmQFjAv8BzAFjFf8B8AHKAaYB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/
-        AswBmQH/AcwBmQFjAf8BzAGZAWMB/wLMAWMB/wLMAWMB/wPxEv8B7AHMAf8BzAGZATAB/wHMAZkBYwL/
-        AcwBYxn/A+MB/wHMAZkBYwH/AcwBmQFjAf8B8AHKAaYF/wHwAcoBpgH/AcwBmQFjAf8BzAGZAWMB/wPj
-        Bf8D6gH/A/EK/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYxH/AswBmQH/AfABygGmAf8CzAGZAf8D8RH/
-        AswBmQH/AfABygGmGv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMJ/wLMAZkB/wHMAZkBYwH/A/EN/wHw
-        AcoBpgH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEw
-        Af8BzAGZATAB/wLMAZkB/wHwAcoBpgL/AewBzAL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjDf8D6gH/
-        A+oB/wHwAcoBpgH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/
-        AcwBmQEwAf8BzAGZATAB/wHMAZkBYwH/A+MB/wPjAf8D8Qr/AewBzAH/AcwBmQEwAf8BzAGZAWMB/wLM
-        AWM5/wPxAf8B8AHKAaYC/wHsAcwO/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYxH/AswBmQH/A9cB/wPx
-        Ef8D6gH/AswBYx7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjCf8D6gH/AcwBmQEwAf8BzAGZAWMJ/wHw
-        AcoBpgH/AcwBmQEwAf8CzAGZAv8B7AHMAf8BzAGZAWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHM
-        AZkBMAH/AcwBmQEwAf8BzAGZAWMB/wHMAZkBYwH/AswBmQL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFj
-        Cf8D4wH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEw
-        Af8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQFjAf8BzAGZATAB/wLM
-        AZkK/wHsAcwB/wHMAZkBMAH/AcwBmQFjAf8CzAFjKf8D8QH/A+oJ/wPxAf8B8AHKAaYB/wHwAcoBpg7/
-        AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEv8B7AHMAf8CzAGZFf8CzAGZAf8B8AHKAaYe/wHsAcwB/wHM
-        AZkBMAH/ApkBYwH/AswBYw3/AfABygGmAf8BmQFjAQAB/wHMAZkBYwH/AcwBmQFjAf8BmQFjATAB/wHM
-        AZkBYwr/AewBzAH/AcwBmQFjAf8CmQEwAf8CmQEwAf8CmQEwAf8CmQEwAf8CzAGZAv8B7AHMAf8D8QL/
-        AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjCv8B7AHMAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZ
-        AWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/ApkBMAH/ApkBMAH/ApkBMAH/ApkBMAH/
-        ApkBMAH/ApkBAAH/AcwBmQFjCv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMi/wHsAcwB/wLMAZkB/wLM
-        AZkB/wPxCv8B7AHMAf8B8AHKAaYB/wPxDv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAcoBpgH/
-        AswBmRH/A/EB/wHMAZkBYwL/AewBzB7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEf8B8AHKAaYB/wHM
-        AZkBYwH/AcwBmQFjAf8CzAGZAf8D8Q3/A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxCv8B7AHM
-        Af8BzAGZATAB/wKZAWMB/wLMAWMJ/wPqAf8CzAGZAf8CzAFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
-        Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
-        AZkBYwH/AcwBmQFjAf8B8AHKAaYK/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYyH/AfABygGmAf8CzAGZ
-        Av8B7AHMCf8B8AHKAaYB/wHwAcoBpgH/A/ES/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EJ/wPx
-        Af8BzAGZAWMB/wPqEf8CzAGZAf8CzAGZIv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxEf8D8QH/
-        A/E2/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EJ/wPqAf8D6gH/AfABygGmAf8BzAGZAWMB/wHM
-        AZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQFj
-        Av8B7AHMAv8B7AHMAf8D8Qr/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8R3/AfABygGmAv8B7AHM
-        Cf8D6gH/AcwBmQFjAf8D8Rb/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QH/A/EF/wHwAcoBpgH/
-        AswBYwH/A/EC/wHsAcwJ/wLMAZkB/wLMAZkF/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/
-        AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
-        Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/
-        ApkBYwH/AswBYwH/A/EB/wPxAf8D8QH/A/EF/wLMAZkB/wKZATAB/wKZATAB/wKZATAB/wHMAZkBYwH/
-        AcwBmQFjAf8BzAGZATAB/wKZATAB/wKZATAB/wHMAZkBYwH/A+oF/wPxAf8D8QH/A/EC/wHsAcwB/wHM
-        AZkBMAH/ApkBYwH/AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EF/wHwAcoBpgL/AewBzAn/
-        AswBmQH/AfABygGmBf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/
+        AcwBmQEmAf8CmQFZAf8CzAFZAf8B8AHKAaYB/wLMAZkB/wLMAZkB/wPXAf8BmQHMAv8BmQHMAv8BmQHM
+        Av8BxgHWAe8B/wHwAfsv/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAGZAf8CzAGZ
+        Af8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7L/8B7AHMAf8BzAGZASYB/wHMAZkBWQH/
+        AswBWQH/AfABygGmAf8CzAGZAf8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7
+        L/8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfse/wHwAcoBpgH/
+        AfABygGmAf8D8Qr/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7
+        M/8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfsz/wHsAcwB/wHM
+        AZkBJgH/AcwBmQFZAf8CzAFZEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7M/8B7AHMAf8BzAGZASYB/wKZ
+        AVkC/wHMAVk5/wHwAcoBpgH/AfABygGmEv8B7AHMAf8BzAGZASYB/wKZAVkC/wHMAVlS/wHsAcwB/wHM
+        AZkBJgH/ApkBWQL/AcwBWRn/A90B/wHwAcoBpgH/AfABygGmAf8D6gX/A9cB/wPdAf8D6hr/AewBzAH/
+        AcwBmQEmAf8BzAGZAVkC/wHMAVkJ/wPxAv8B7AHMAf8D6hH/A/EC/wHsAcwB/wPxEf8D6gL/AewBzAH/
+        A/EG/wHsAcwB/wHMAZkBJgH/AcwBmQFZAv8BzAFZIv8B7AHMAf8D8RL/AewBzAH/AfABygGmAf8CzAGZ
+        Af8D6gr/AewBzAH/AcwBmQEmAf8BzAGZAVkC/wHMAVkB/wPxAf8D8Sn/A/EC/wHsAcwC/wHsAcwC/wHs
+        AcwC/wHsAcwB/wPxCv8B7AHMAf8BzAGZASYB/wKZAVkC/wHMAVkV/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AVkC/wHsAcwB/wPqAf8CzAFZAf8CzAGZAf8CzAGZAf8CzAGZAf8D6hL/AewBzAH/AcwBmQEmAf8BzAGZ
+        AVkC/wHMAVkK/wHsAcwB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wLMAZkB/wPjAf8D4wH/AswBmQH/
+        AcwBmQEmAf8CzAFZAf8D4wH/A+MB/wLMAZkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkC/wHsAcwG/wHs
+        AcwB/wHMAZkBJgH/ApkBWQL/AcwBWRX/AfABygGmAf8B8AHKAaYB/wHwAcoBpgL/AewBzBX/A+MB/wHw
+        AcoBpgL/AewBzA7/AewBzAH/AcwBmQEmAf8CmQFZAv8BzAFZAf8B8AHKAaYB/wLMAZkB/wHwAcoBpiL/
+        AewBzAH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBWQH/AfABygGmAv8B7AHMAf8D6gL/AewBzAH/
+        AcwBmQEmAf8CmQFZAv8BzAFZFf8CzAGZAf8CzAFZAf8CzAFZAf8CzAFZAf8D4wX/AswBWQH/AswBWQH/
+        AswBWQH/AswBWQH/A+MS/wHsAcwB/wHMAZkBJgH/AcwBmQFZAv8BzAFZDv8B7AHMAf8B8AHKAaYB/wHM
+        AZkBWQH/AZkBWQEmAf8BmQFZASYB/wKZASYB/wGZAVkBJgH/AcwBmQFZAf8BmQFZASYB/wGZAVkBJgH/
+        AZkBWQEmAf8BmQFZASYB/wHMAZkBWQH/AfABygGmAv8B7AHMCv8B7AHMAf8BzAGZASYB/wKZAVkC/wHM
+        AVkR/wPqAf8CzAGZAf8BzAGZAVkB/wLMAZkR/wPxAf8BzAGZAVkB/wLMAZkB/wPxEv8B7AHMAf8BzAGZ
+        ASYB/wKZAVkC/wHMAVkB/wPqAf8B8AHKAaYB/wHMAZkBWQH/A90Z/wPxAf8CzAFZAf8BzAGZAVkB/wHM
+        AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQL/AewBzAH/
+        AcwBmQEmAf8CmQFZAv8BzAFZFf8B8AHKAaYB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/
+        AswBmQH/AcwBmQFZAf8BzAGZAVkB/wLMAVkB/wLMAVkB/wPxEv8B7AHMAf8BzAGZASYB/wHMAZkBWQL/
+        AcwBWRn/A+MB/wHMAZkBWQH/AcwBmQFZAf8B8AHKAaYF/wHwAcoBpgH/AcwBmQFZAf8BzAGZAVkB/wPj
+        Bf8D6gH/A/EK/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWRH/AswBmQH/AfABygGmAf8CzAGZAf8D8RH/
+        AswBmQH/AfABygGmGv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkJ/wLMAZkB/wHMAZkBWQH/A/EN/wHw
+        AcoBpgH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEm
+        Af8BzAGZASYB/wLMAZkB/wHwAcoBpgL/AewBzAL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZDf8D6gH/
+        A+oB/wHwAcoBpgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/
+        AcwBmQEmAf8BzAGZASYB/wHMAZkBWQH/A+MB/wPjAf8D8Qr/AewBzAH/AcwBmQEmAf8BzAGZAVkB/wLM
+        AVk5/wPxAf8B8AHKAaYC/wHsAcwO/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWRH/AswBmQH/A9cB/wPx
+        Ef8D6gH/AswBWR7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZCf8D6gH/AcwBmQEmAf8BzAGZAVkJ/wHw
+        AcoBpgH/AcwBmQEmAf8CzAGZAv8B7AHMAf8BzAGZAVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHM
+        AZkBJgH/AcwBmQEmAf8BzAGZAVkB/wHMAZkBWQH/AswBmQL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZ
+        Cf8D4wH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEm
+        Af8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQFZAf8BzAGZASYB/wLM
+        AZkK/wHsAcwB/wHMAZkBJgH/AcwBmQFZAf8CzAFZKf8D8QH/A+oJ/wPxAf8B8AHKAaYB/wHwAcoBpg7/
+        AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEv8B7AHMAf8CzAGZFf8CzAGZAf8B8AHKAaYe/wHsAcwB/wHM
+        AZkBJgH/ApkBWQH/AswBWQ3/AfABygGmAf8BmQFZAQAB/wHMAZkBWQH/AcwBmQFZAf8BmQFZASYB/wHM
+        AZkBWQr/AewBzAH/AcwBmQFZAf8CmQEmAf8CmQEmAf8CmQEmAf8CmQEmAf8CzAGZAv8B7AHMAf8D8QL/
+        AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZCv8B7AHMAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZ
+        AVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/ApkBJgH/ApkBJgH/ApkBJgH/ApkBJgH/
+        ApkBJgH/ApkBAAH/AcwBmQFZCv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVki/wHsAcwB/wLMAZkB/wLM
+        AZkB/wPxCv8B7AHMAf8B8AHKAaYB/wPxDv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAcoBpgH/
+        AswBmRH/A/EB/wHMAZkBWQL/AewBzB7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEf8B8AHKAaYB/wHM
+        AZkBWQH/AcwBmQFZAf8CzAGZAf8D8Q3/A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxCv8B7AHM
+        Af8BzAGZASYB/wKZAVkB/wLMAVkJ/wPqAf8CzAGZAf8CzAFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+        Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+        AZkBWQH/AcwBmQFZAf8B8AHKAaYK/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWSH/AfABygGmAf8CzAGZ
+        Av8B7AHMCf8B8AHKAaYB/wHwAcoBpgH/A/ES/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EJ/wPx
+        Af8BzAGZAVkB/wPqEf8CzAGZAf8CzAGZIv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxEf8D8QH/
+        A/E2/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EJ/wPqAf8D6gH/AfABygGmAf8BzAGZAVkB/wHM
+        AZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQFZ
+        Av8B7AHMAv8B7AHMAf8D8Qr/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8R3/AfABygGmAv8B7AHM
+        Cf8D6gH/AcwBmQFZAf8D8Rb/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QH/A/EF/wHwAcoBpgH/
+        AswBWQH/A/EC/wHsAcwJ/wLMAZkB/wLMAZkF/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/
+        AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
+        Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/
+        ApkBWQH/AswBWQH/A/EB/wPxAf8D8QH/A/EF/wLMAZkB/wKZASYB/wKZASYB/wKZASYB/wHMAZkBWQH/
+        AcwBmQFZAf8BzAGZASYB/wKZASYB/wKZASYB/wHMAZkBWQH/A+oF/wPxAf8D8QH/A/EC/wHsAcwB/wHM
+        AZkBJgH/ApkBWQH/AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EF/wHwAcoBpgL/AewBzAn/
+        AswBmQH/AfABygGmBf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/
         A/EB/wPxAv8B7AHMAf8CzAGZAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/A+oB/wHwAcoBpgH/AswBmQH/
-        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/
-        AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
-        Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxAf8D8QH/
-        A/EB/wPxAf8D8QH/AcwBmQFjAf8CmQEwAf8CmQEwAf8CmQEwAf8B8AHKAaYB/wPxAf8BzAGZAWMB/wKZ
-        ATAB/wKZATAB/wKZATAC/wHsAcwB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLM
-        AWMB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/AswBmQL/AewBzAb/AewBzAH/AswBmQH/
-        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EB/wPx
+        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+        AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
+        Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxAf8D8QH/
+        A/EB/wPxAf8D8QH/AcwBmQFZAf8CmQEmAf8CmQEmAf8CmQEmAf8B8AHKAaYB/wPxAf8BzAGZAVkB/wKZ
+        ASYB/wKZASYB/wKZASYC/wHsAcwB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLM
+        AVkB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/AswBmQL/AewBzAb/AewBzAH/AswBmQH/
+        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EB/wPx
         Af8B8AHKAaYB/wPXAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
-        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/ApkBYwH/AswBYwH/
+        A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/ApkBWQH/AswBWQH/
         A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/
-        A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxAf8D8QH/A/EB/wPx
-        Av8B7AHMAf8BzAGZAWMB/wKZATAB/wGZAWMBMAH/AZkBYwEwAf8CzAGZAv8B7AHMAf8BmQFjATAB/wGZ
-        AWMBMAH/ApkBMAH/ApkBMAH/AfABygGmAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/ApkBYwH/
-        AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wHwAcoBpgH/AfABygGmAf8B8AHKAaYB/wHw
-        AcoBpgH/AfABygGmAv8B7AHMAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/
-        ApkBYwH/AswBYwL/AewBzAH/A/EB/wHwAcoBpgH/AswBmQH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
+        A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxAf8D8QH/A/EB/wPx
+        Av8B7AHMAf8BzAGZAVkB/wKZASYB/wGZAVkBJgH/AZkBWQEmAf8CzAGZAv8B7AHMAf8BmQFZASYB/wGZ
+        AVkBJgH/ApkBJgH/ApkBJgH/AfABygGmAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/ApkBWQH/
+        AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wHwAcoBpgH/AfABygGmAf8B8AHKAaYB/wHw
+        AcoBpgH/AfABygGmAv8B7AHMAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/
+        ApkBWQH/AswBWQL/AewBzAH/A/EB/wHwAcoBpgH/AswBmQH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
         A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
-        AcwC/wHsAcwC/wHsAcwB/wKZATAB/wKZAWMB/wLMAWMC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
+        AcwC/wHsAcwC/wHsAcwB/wKZASYB/wKZAVkB/wLMAVkC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
         AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
-        AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wKZATAB/wKZAWMB/wLMAWMC/wHs
+        AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wKZASYB/wKZAVkB/wLMAVkC/wHs
         AcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxAf8D8QL/AewBzAH/AfABygGmAf8CzAGZAv8B7AHMAv8B7AHM
         Af8CzAGZAf8CzAGZAf8B8AHKAaYC/wHsAcwB/wPxAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHM
-        Af8CmQEwAf8CmQFjAf8CzAFjAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/AewBzAH/
+        Af8CmQEmAf8CmQFZAf8CzAFZAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/AewBzAH/
         AswBmQH/AfABygGmAf8CzAGZAf8B8AHKAaYB/wPxAf8D8QL/AewBzAL/AewBzAL/AewBzAL/AewBzAL/
-        AewBzAL/AewBzAL/AewBzAL/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8Qb/AewBzAL/AewBzAL/
-        AewBzD7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8U7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFj
-        Af8D8U7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8RX/A/EB/wPjAv8B7AHMLv8B7AHMAf8CmQEw
-        Af8BpAKgAf8CmQEwAf8BzAGZAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+        AewBzAL/AewBzAL/AewBzAL/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8Qb/AewBzAL/AewBzAL/
+        AewBzD7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8U7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZ
+        Af8D8U7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8RX/A/EB/wPjAv8B7AHMLv8B7AHMAf8CmQEm
+        Af8BpAKgAf8CmQEmAf8BzAGZAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
         AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAZkB/wLMAZkB/wHMAZkBYwH/ApkBMAH/AaQCoAH/ApkBMAH/AcwBmQFjAf8CzAGZAf8CzAGZ
+        AZkB/wLMAZkB/wLMAZkB/wHMAZkBWQH/ApkBJgH/AaQCoAH/ApkBJgH/AcwBmQFZAf8CzAGZAf8CzAGZ
         Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
-        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8BzAGZAWMB/wKZATAB/wGk
-        AqAB/wKZATAB/wHMAZkBYwH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
+        Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8BzAGZAVkB/wKZASYB/wGk
+        AqAB/wKZASYB/wHMAZkBWQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
         AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
-        AswBmQH/AswBmQH/AcwBmQFjAf8CmQEwAf8BpAKgAf8CmQEwAf8BzAGZAWMB/wLMAZkB/wLMAZkB/wLM
+        AswBmQH/AswBmQH/AcwBmQFZAf8CmQEmAf8BpAKgAf8CmQEmAf8BzAGZAVkB/wLMAZkB/wLMAZkB/wLM
         AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
-        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wHMAZkBYwH/ApkBMAX/AswBYwH/
-        AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZ
-        AWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/
-        AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/A8wF/wLMAWMB/wHM
-        AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
-        Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
-        AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHwAcoBpgH/A/EB/wLM
-        AWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/
-        AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZ
-        ATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZAWMB/wPMBf8CzAFj
-        Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
-        AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
-        Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8DzAH/AUIBTQE+
+        AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wHMAZkBWQH/ApkBJgX/AswBWQH/
+        AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZ
+        AVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/
+        AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/A8wF/wLMAVkB/wHM
+        AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+        Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+        AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHwAcoBpgH/A/EB/wLM
+        AVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/
+        AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZ
+        ASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZAVkB/wPMBf8CzAFZ
+        Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+        AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+        Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8DzAH/AUIBTQE+
         BwABPgMAASgDAAFgAwABMAMAAQEBAAEBBQABQAECFgAD//8A/wBDAAs=
 </value>
   </data>
@@ -306,111 +306,108 @@
     <value>
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
-        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACw
-        FwAAAk1TRnQBSQFMAgEBBAEAAQgBAAEIAQABFQEAARQBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFU
+        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABc
+        FgAAAk1TRnQBSQFMAgEBBAEAAVgBAAFYAQABFQEAARQBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFU
         AwABKAMAAQEBAAEgBQABgAE0/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
-        /wD/AP8A/wD/AP8A/wD/ADcAAwQBBVAAAwQBBUQAAUgCSQFaAU8BZwGBAdEBJQFXAY0B7QE3AV0BigHt
-        AWABcgGGAcgBXgFgAWIBgAMkASyUAAFAAVIBQQFwAUkBZgFLAZADBQEHSAABQAFSAUEBcAFJAWYBSwGQ
-        AwUBBzwAAkcBSAFZASQBUwGFAf8BCgFHAYcB/wEhAVkBlQH/ASMBWwGZAf8BGgFUAZQB/wEbAVABjAH/
-        AUcBZgGNAfYBaAFrAW8BlQMqATOIAAE+AVABPwFvAYYBsAGJAd0BjAG2AZEB4AFKAWYBSwGQAwUBB0AA
-        AT4BUAE/AW8BhgGwAYkB3QGMAbYBkQHgAUoBZgFLAZADBQEHMAADCQELAVwBXwFjAYIBJwFVAYYB/wEO
-        AUoBiAH/ARYBTwGKAf8BIAFYAZQB/wElAVsBmAH/ASQBWgGWAf8BIwFZAZYB/wEbAVUBlQH/ARkBTwGM
-        Af8BOwFgAYwB+wFmAW4BeAGlAUIBQwFEAVQDBwEJKwAEAQECAwMBBAMgASoDAAEBPAABPAFPAT0BbgF5
-        Aa0BfwHcAbwB+gHQAf0BvwH+AdQB/wGCAbYBiwHgAUkBZgFLAZADBQEHOAABPAFPAT0BbgF5Aa0BfwHc
-        AbwB+gHQAf0BvwH+AdQB/wGCAbYBiwHgAUkBZgFLAZADBQEHKAADBwEJAWYBbgF3AaYBCAFCAX0B/wEQ
-        AUsBiAH/ARcBTwGJAf8BFgFOAYoB/wEgAVcBlAH/ASYBXAGZAf8BIQFUAY0B/wEYAUUBdgH/AR0BTgGF
-        Af8BIAFXAZQB/wEcAVQBlQH/ARQBTQGNAf8BGgFNAYYB/wFMAU0BUAFlIAADDAEPAzsBUQNZAYgCbgFt
-        AcACegF5AfQDlgH/A3kB4gNRAXk0AAE4AUsBOQFrAXIBpwF4AdoBpQH0AbwB/QGVAfgBtAH/AZcB+gG3
-        Af8BqwH9AcYB/wF/AbYBhwHgAUgBZQFJAY8DBQEHMAABOAFLATkBawFyAacBeAHaAaUB9AG8Af0BlQH4
-        AbQB/wGXAfoBtwH/AasB/QHGAf8BfwG2AYcB4AFEAWIBRwGhATwBVgFYAYIBQAFyAXgBlgE5AU0BUQF4
-        AxYBHxgAAUgBSgFMAWEBDQFFAX4B/wEQAUgBggH/ARUBSwGFAf8BFgFPAYoB/wEVAU4BiQH/ASABVwGU
-        Af8BIwFYAZMB/wEoAVoBkgH/ATsBawGkAf8BKQFXAYsB/wEcAUkBegH/ARkBSQF+Af8BHwFUAZAB/wEZ
-        AVIBkQH/AUcBTQFTAXAUAAMVARsDTQFsA3MBtwKXAZYB/wO9Af8B0QLQAf8B1QHUAdUB/wGtAcoBqwH/
-        AccB1wHFAf8BvQGvAa0B/wGkAZsBmAH/Am4BbQGxAzUBSCgAATYBSAE2AWkBbgGhAXEB1wGgAe4BswH9
-        AYEB7wGgAf8BcwHxAZgB/wF4AfMBnQH/AYsB9gGsAf8BqgH6AcMB/wF/AbIBhQHfAUQBYgFFAY0DBQEH
-        KAABNgFIATYBaQFuAaEBcQHXAaAB7gGzAf0BgQHvAaAB/wFzAfEBmAH/AXgB8wGdAf8BiwH2AawB/wF9
-        AcEBmwH/AUUB1AHcAf0BPQHvAv8BMQHhAv8BKgHiAv8BLAGmAcIB5QEkASUBJgE4FAABRQFJAU8BcAEO
-        AUYBgAH/AREBPgFuAf8BDAE2AWQB/wEQAUgBgQH/ARQBTgGJAf8BIAFWAZMB/wEgAVABiAH/AUcBewG5
-        Af8BVwGQAdIB/wFTAY0BzgH/AUcBewG5Af8BLwFdAZIB/wEZAUUBdQH/AQsBPgF3Af8BTwFSAVYBbRAA
-        A2QBkAKnAaYB/wHNAssB/wHcAtkB/wHdAtoB/wHVAdABzwH/AdMBzQHMAf8B1wHVAdYB/wGGAcQBfgH/
-        AbIB1wGrAf8BvQGtAakB/wGlAYoBgwH/Aa4BmwGXAf8BlwGUAZIB/wNbAYcgAAE2AUgBNgFpAXgBoAF5
-        AdYBmgHTAaMB8gGAAecBmgH/AWQB5QGGAf8BWwHmAYEB/wFgAegBhwH/AXEB7gGVAf8BkQH0Aa0B/wGm
-        AeIBtQH1AYcBrgGKAd0BQgFfAUIBiwMFAQcgAAE2AUgBNgFpAXgBoAF5AdYBmgHTAaMB8gGAAecBmgH/
-        AWQB5QGGAf8BWwHmAYEB/wFgAegBhwH/AVEBtAF5Af8BUgHcAeYB/wFLAfIC/wE9AeUB/QH/ATMB3wH9
-        Af8BLAHbAv8BKAHjAv8BJgGdAb4B5AMUARsQAAE/AUQBSgFsAR8BUAGIAf8BXgGNAckB/wFRAXsBswH/
-        ASQBUAGDAf8BFQFKAYQB/wEdAU4BiQH/AUIBcgGuAf8BWwGSAdMB/wFVAYwBzAH/AVQBiwHLAf8BVAGN
-        Ac4B/wFUAY4B0AH/AUkBfgG9Af8BJQFWAY0B/wFYAV4BZQGIDAADDAEPAqYBpwH/AdIBzAHLAf8BwQG5
-        AbcB/wHMAcYBxQH/Ac8CygH/Ac4ByAHGAf8BzQHHAcUB/wHOAskB/wHSAs8B/wHeAtwB/wHaAdQB1QH/
-        AbEBnQGYAf8BpQGKAYMB/wGoAY4BiAH/AaoBoAGeAf8DdgG3AzoBThQAAQ8BEAEPARQBLQE2AS0BSgEt
-        ATYBLQFKATUBaAE2Aa0BbwHVAYMB+gFSAdkBcAH/AUgB2gFrAf8BTQHeAXEB/wFhAeQBgwH/AYIB7AGf
-        Af8BagGoAXEB2wEyAT0BMwFUATABOQEwAU0BGQEaARkBIhwAASgBKwEqAUIBNAFWAVEBoAEtATYBLQFK
-        ASQBYAFDAdEBRgGeAW8B/AFIAcABZAH/AUABxAFhAf8BLQGfAWUB/wEeAcAB5QH/AVYB7gL/AUYB5QH8
-        Af8BQgHoAf0B/wE3AeQB/gH/AUsBwgHTAfABZwGeAaYB1QFPAeQC/wE2AU0BUwF8EAABVgFfAWwBlQFh
-        AZQB1QH/AXIBpQHjAf8BdgGoAeQB/wF6AaYB4QH/AWgBjwHIAf8BPQGAAbIB/wFdAZUB0gH/AWIBkAHR
-        Af8BXQGPAdAB/wFZAY4BzgH/AVcBjgHNAf8BVAGMAcwB/wFUAY0BzQH/AVMBjgHPAf8BUwGJAcUB+gFk
-        AX4BmwHFAioBKwE0BAADGgEhA7gB/wHNAcYBxQH/AbcBrgGsAf8BuwG0AbEB/wHGAcEBvwH/AcwByAHG
-        Af8B1wHTAdQB/wHiAeAB3wH/AeYC4gH/AekB4wHiAf8B4gHbAdoB/wHmAuEB/wHJAb4BvQH/AacBjgGH
-        Af8BpQGKAYMB/wGvAZsBlwH/AaICngH/A0MBWhwAATYBYwE3AaQBbQHLAX4B9wFOAdMBaAH/AToB0QFa
-        Af8BPAHSAVwB/wFTAdoBcgH/AXsB5QGVAf8BPgF3AT8BwQMIAQsgAAEhAiIBMQFSAb8BygHqAUoB8wL/
-        AUEBeAF/AbcBMQHgAfoB/wEqAdgB9gH/ASUByAHkAf8BHwHBAd0B/wEYAdcC/wEiAdAC/wFZAegB/AH/
-        AUoB5wH8Af8BRgHqAf0B/wE9Ae8C/wE2AUABQQFqBAABbgHUAeYB/QE8AXkBiQGiDAABWQFeAWUBfgFq
-        AZ4B3wH/AW0BoAHgAf8BcAGhAd4B/wF4AaMB3wH/AXgBpQHdAf8BPQGtAdcB/wEOAb4B4QH/AQ0BrwHX
-        Af8BMgGgAc8B/wFUAZUBzwH/AV0BkQHPAf8BYAGPAc8B/wFcAY8BzwH/AVcBjgHNAf8BVQGNAcwB/wFO
-        AYkBywH/AVsBjAHDAfYCHAEdASMEAAMCAQMDsgH/AegC5wH/AecB4wHkAf8B6gHnAegB/wHpAeUB5gH/
-        AesB5QHmAf8B7gLnAf8B8wHuAe0B/wHtAuYB/wHXAcwBywH/AdEBxQHEAf8B1AHLAcoB/wHdAtYB/wHg
-        AtsB/wG1AaEBngH/AaUBigGDAf8BrgGaAZQB/wKEAYMBwxwAATYBYwE3AaQBbwHKAX8B9wFLAc0BYwH/
-        ATMByQFQAf8BMwHLAVEB/wFLAdIBZgH/AXgB3wGOAf8BOQFzAToBvwMIAQsgAAFDAVYBVwGLAXID/wFc
-        AfwC/wFOA/8BQAH1Av8BNgHwAv8BLgHsAv8BJwHmAv8BHgHcAv8BJwHcAv8BXwHqAf4B/wFOAecB/AH/
-        AUsB7AH9Af8BPAHoAf4B/wE0AZQBqQHXAUEBagFwAaoBRAHmAv8BOQFWAV4BhgQAAxoBIAFwAX4BkgGx
-        AWIBlwHaAf8BagGdAd4B/wFvAaAB3gH/AXsBowHgAf8BZQGjAdcB/wEUAbAB2AH/AQABuwHiAf8BDAHB
-        AecB/wEAAb0B5QH/AQABvQHkAf8BBAG4AeAB/wETAa4B2QH/ATMBngHNAf8BUQGUAcwB/wFgAY8BzwH/
-        AV0BjwHQAf8BUQGLAcwB/wFLAU0BUAFgDAADOwFLA4UBtAHHAcYBxQH/AeMB4AHhAf8B8wHtAe4B/wHu
-        AecB6AH/AfIC7gH/AfgC9QH/AfQC8QH/AfEC7AH/AewB6AHnAf8B6QHjAeIB/wHjAd0B3AH/AdgC1AH/
-        AfEB6wHsAf8B0gHJAcgB/wGxAZ4BmQH/AokBiAHDHAABNgFjATYBpQFyAcgBgAH3AUgByAFdAf8BLQHC
-        AUcB/wEsAcMBRwH/AUcBywFeAf8BeQHcAYwB/wE4AXMBOQG+AwgBCyQAATkBQQFCAWoBQAFUAVUBhwE9
-        AVMBVQGHAS0BbAFVAdUBQwGWAXkB+wEsAZUBagH/AR4BkQFfAf8BHAGQAV8B/wErAZMBbgH/AWsB5wHz
-        Af8BXwHzAv8BTgHsAf0B/wFBAecB/QH/ATcB5gL/ATMB7gL/ASkBtwHXAfEBGwIcASgEAAFbAWABZwGB
-        AWABlwHbAf8BZgGcAd4B/wFuAZ8B3gH/AXgBoQHeAf8BVAGjAdQB/wEKAbEB2AH/AQABvQHlAf8BAAG7
-        AeQB/wELAb8B5QH/AQABugHjAf8BAAG8AeUB/wEAAb0B5gH/AQABvQHlAf8BAAG8AeMB/wEDAbQB2wH/
-        ASEBpAHRAf8BQAGSAcoB/wFsAYQBoAHKGAADHwEnA24BkAG+Ar0B/wHaAdcB2QH/AfIB7QHuAf8B+AL1
-        Af8B8wLuAf8B6wLkAf8B5gHgAd8B/wHiAtoB/wHkAt0B/wH0Ae0B7gH/AfgB8gH0Af8B7AHnAekB/wHB
-        Ab8BwAH/A0YBWhwAATYBYwE2AaUBcAHFAX0B9wFCAcIBVQH/ASYBuwE+Af8BJQG8AT4B/wFBAcYBVwH/
-        AXYB1wGHAf8BOAFyATkBvgMIAQswAAE2AWMBNgGlAXABxQF9AfcBQgHCAVUB/wEmAbsBPgH/ASUBvAE+
-        Af8BQQHGAVcB/wFXAaIBcgH/AWcB8QH3Af8BWAH7Av8BRgHuAv8BPgHyAv8BMwHOAeYB9wEuATIBMwFP
-        CAADAQECAiIBIwErAWoBdwGJAaUBbgGcAdQB+gEzAaUB0wH/AQABtwHeAf8BAAG8AeQB/wEAAboB4wH/
-        ARYBwQHmAf8BOQHHAegB/wEkAcQB5wH/AQ0BwAHmAf8BAAG8AeUB/wEAAboB4wH/AQABuwHkAf8BAAG8
-        AeUB/wEAAbwB5QH/AQ4BvgHoAf8BfQGkAcQB3QMWARscAAMHAQkDTAFgA5YBxgHNAcwBzQH/AeoB5gHo
-        Af8B6wHlAecB/wHqAeYB6AH/AeAB3gHfAf8B2gHXAdkB/wHJAsgB/wOmAeEDdwGcAzABPCAAATYBYwE2
-        AaUBgwHJAYsB9wFXAcYBZwH/ATwBvgFNAf8BOwG+AU0B/wFUAccBZgH/AYgB2QGVAf8BOQFyAToBvgMI
-        AQswAAE2AWMBNgGlAYMByQGLAfcBVwHGAWcB/wE8Ab4BTQH/ATsBvgFNAf8BVAHHAWYB/wGIAdkBlQH/
-        ATMBZwE3AcoBQwFjAWQBlwFJAYoBjwGxAT0BWAFaAYkDGgElFAADAgEDAWUBlwG6Ad0BAgG/AekB/wEA
-        AbsB5QH/AQABugHiAf8BKAHDAeUB/wFEAcUB5QH/AToBwAHjAf8BPgHCAeQB/wFBAcYB5wH/ATQBxwHp
-        Af8BGwHCAeYB/wECAbsB4wH/AQABvAHmAf8BFAHLAfUB/wEsAdYC/wGIAcoC/wGDAZYBqwHBAwgBCiQA
-        AycBMAN1AZYDkgG9A3cBmQNTAWkDPAFLAxgBHiwAATYBYwE2AaUBpgHUAasB9wGIAdMBkgH/AW8BzAF6
-        Af8BbQHNAXoB/wGGAdUBkQH/AbMB5AG6Af8BOgFyAToBvwMIAQswAAE2AWMBNgGlAaYB1AGrAfcBiAHT
-        AZIB/wFvAcwBegH/AW0BzQF6Af8BhgHVAZEB/wGzAeQBugH/AToBcgE6Ab8DCAELIAABSQFLAU8BYAFf
-        AbIB8wH/ARgB0QH+Af8BKQHQAfkB/wFEAdEB9QH/AUwBzQHwAf8BOwHEAegB/wE2AcAB4wH/ATQBvgHh
-        Af8BNwHAAeQB/wE8AcEB5AH/AUEBxAHmAf8BRwHRAfMB/wFHAdgB+wH/AUEB2wL/ATEB1wH+Af8BhwHH
-        AfsB/wGTAccC/wFsAXkBhwGebAABNgFjATYBpQExAWwBMQG7ATEBbAExAbsBMQFsATEBuwExAWwBMQG7
-        ATEBbAExAbsBMQFsATEBuwExAWwBMQG7AwgBCzAAATYBYwE2AaUBMQFsATEBuwExAWwBMQG7ATEBbAEx
-        AbsBMQFsATEBuwExAWwBMQG7ATEBbAExAbsBMQFsATEBuwMIAQsgAAFxAYABlgGyAVoBsgH1Af8BMgHW
-        Af4B/wFXAdoB/gH/AVIB1gH9Af8BTwHVAfwB/wFQAdUB/AH/AUoB0QH3Af8BQgHKAe8B/wE9AcUB6AH/
-        AUEByQHsAf8BTQHTAfgB/wFVAdkB/gH/AVUB2gH9Af8BWAHcAf4B/wFnAdUB/gH/AY8BxQH7Af8BegGL
-        AZ0BrwEsAS0BLgE4/wAFAAEYAhkBHwE8AT8BQQFOAVgBawFxAYMBYgGmAboBzQFUAdEB9AH8AUoB1QH9
-        Af8BSgHVAf0B/wFOAdUB/AH/AVEB1gH9Af8BUQHWAfsB/wFTAdgB/AH/AVIB2AH9Af8BTQHZAf0B/wFZ
-        AdMB/AH/AXUBxwH4Af8BegGNAaIBtgE7ATwBPgFL/wAdAAElASYBJwEvAVYBagFvAYIBZwGmAbkBywFR
-        AdQB+gH/AU0B1gH8Af8BTgHYAf0B/wFNAdgB/QH/AVUB1gH4Af0BbAHBAecB9AGBAa0B2AHqAUcBSgFO
-        AV3/ADEAATABMgEzAT4BUQFqAXABgQFgAZMBoQGuAV8BkgGhAa8BNAE7ATwBRwIlASYBLgEdAh4BJWgA
-        AUIBTQE+BwABPgMAASgDAAFUAwABKAMAAQEBAAEBBQAB4AEBFgAD//EACv8B8AEACv8B8AEAAf8B3wH/
-        Af4C/wGAA/8B8AEAAf8BjwH/AfwBfwH/AQABPwL/AfABAAH/AQcB/wH4AT8B/AEAAQcB/gEPAfABAAH+
-        AQMB/wHwAR8B+AEAAQcB+AEHAfABAAH8AQEB/wHgAQEB+AEAAQcBwAEBAfABAAH4AQAB/wHAAQAB+AEA
-        AQcBgAEAAfABAAHwAQABfwGAAQABeAEAAQcCAAEwAQAB4AEAAX8CAAF4AQABAQIAARABAAH8AQEB/gEA
-        AQIBcAEAAQECAAEQAQAB/AEBAf4CAAFAAQABAwGAAQABEAEAAfwBAQH/AgABQAEAAQcB4AEAARABAAH8
-        AQEB/wHgAQABwAEAAQMB+AEAATABAAH8AQEB/wHgAQEB8AEAAQEB/wEBAfABAAH8AQEB/wHgAQ8B8AEA
-        AQEC/wHwAQAB/AEBAf8B4AEPAfABAAEBAv8B8AEABf8B8AEAAQcC/wHwAQAG/wEAAR8C/wHwAQAG/wHg
-        AT8C/wHwAQAL
+        /wD/AP8A/wD/AP8A/wD/ADcAAwQBBVAAAwQBBUQAAzcBWgFYAlwB0QFQAV0BaQHtAVMBXQFpAe0DWwHI
+        A0cBgAMfASyUAANAAXABSwFMAUsBkAMFAQdIAANAAXABSwFMAUsBkAMFAQc8AAM2AVkBGgFJAYUB/wEA
+        AT0BhwH/ARcBTwGVAf8BGQFRAZkB/wEQAUoBlAH/AREBRgGMAf8BSAFiAXEB9gNOAZUDIwEziAABPwFA
+        AT8BbwFhAWMBYQHdAWMBZgFkAeABSwFMAUsBkAMFAQdAAAE/AUABPwFvAWEBYwFhAd0BYwFmAWQB4AFL
+        AUwBSwGQAwUBBzAAAwgBCwNHAYIBHQFLAYYB/wEEAUABiAH/AQwBRQGKAf8BFgFOAZQB/wEbAVEBmAH/
+        ARoBUAGWAf8BGQFPAZYB/wERAUsBlQH/AQ8BRQGMAf8BMgFfAYIB+wNTAaUDNAFUAwcBCSsABAEBAgMD
+        AQQDHQEqAwABATwAAT8BQAE/AW4DYQHcAbIB3AG6Af0BvwH+AdQB/wFiAWYBYwHgAUsBTAFLAZADBQEH
+        OAABPwFAAT8BbgNhAdwBsgHcAboB/QG/Af4B1AH/AWIBZgFjAeABSwFMAUsBkAMFAQcoAAMHAQkDVAGm
+        AQABOAFzAf8BBgFBAYgB/wENAUUBiQH/AQwBRAGKAf8BFgFNAZQB/wEcAVIBmQH/ARcBSgGNAf8BDgE7
+        AWwB/wETAUQBhQH/ARYBTQGUAf8BEgFKAZUB/wEKAUMBjQH/ARABQwGGAf8DOwFlIAADCwEPAzIBUQNJ
+        AYgDWgHAA2UB9AOWAf8DYQHiA0QBeTQAAz4BawFhAWIBYQHaAaUB1gGyAf0BlQH4AbQB/wGXAfoBtwH/
+        AasB/QHGAf8BYgFmAWMB4AFLAUwBSwGPAwUBBzAAAz4BawFhAWIBYQHaAaUB1gGyAf0BlQH4AbQB/wGX
+        AfoBtwH/AasB/QHGAf8BYgFmAWMB4AFRAVIBUQGhA0cBggFNAk4BlgNDAXgDFgEfGAADOgFhAQMBOwF0
+        Af8BBgE+AYIB/wELAUEBhQH/AQwBRQGKAf8BCwFEAYkB/wEWAU0BlAH/ARkBTgGTAf8BHgFQAZIB/wEx
+        AWEBpAH/AR8BTQGLAf8BEgE/AXAB/wEPAT8BdAH/ARUBSgGQAf8BDwFIAZEB/wNAAXAUAAMUARsDPwFs
+        A1cBtwKXAZYB/wO9Af8B0QLQAf8B1QHUAdUB/wGtAcoBqwH/AccB1wHFAf8BvQGvAa0B/wGkAZsBmAH/
+        A1YBsQMuAUgoAAM9AWkBXQFfAV0B1wGgAdABqQH9AYEB7wGgAf8BaQHxAZgB/wFuAfMBnQH/AYsB9gGs
+        Af8BqgH6AcMB/wFeAWIBXwHfA0oBjQMFAQcoAAM9AWkBXQFfAV0B1wGgAdABqQH9AYEB7wGgAf8BaQHx
+        AZgB/wFuAfMBnQH/AYsB9gGsAf8BcwHBAZsB/wFAAbwBvgH9ATMB7wL/AScB4QL/ASAB4gL/AVgBagFu
+        AeUDJgE4FAADQAFwAQQBPAGAAf8BBwE0AWQB/wECASwBWgH/AQYBPgGBAf8BCgFEAYkB/wEWAUwBkwH/
+        ARYBRgGIAf8BPQFxAbkB/wFNAZAB0gH/AUkBjQHOAf8BPQFxAbkB/wElAVMBkgH/AQ8BOwFrAf8BAQE0
+        AW0B/wM/AW0QAANMAZACpwGmAf8BzQLLAf8B3ALZAf8B3QLaAf8B1QHQAc8B/wHTAc0BzAH/AdcB1QHW
+        Af8BhgHEAXQB/wGyAdcBqwH/Ab0BrQGpAf8BpQGKAYMB/wGuAZsBlwH/AZcBlAGSAf8DSQGHIAADPQFp
+        A2AB1gF3AYsBewHyAYAB5wGaAf8BWgHlAYYB/wFRAeYBgQH/AVYB6AGHAf8BZwHuAZUB/wGRAfQBrQH/
+        AYABmQGEAfUBYQFjAWEB3QNKAYsDBQEHIAADPQFpA2AB1gF3AYsBewHyAYAB5wGaAf8BWgHlAYYB/wFR
+        AeYBgQH/AVYB6AGHAf8BRwG0AW8B/wFIAdwB5gH/AUEB8gL/ATMB5QH9Af8BKQHfAf0B/wEiAdsC/wEe
+        AeMC/wFVAWQBaQHkAxQBGxAAAz8BbAEVAUYBiAH/AVQBjQHJAf8BRwFxAbMB/wEaAUYBgwH/AQsBQAGE
+        Af8BEwFEAYkB/wE4AWgBrgH/AVEBkgHTAf8BSwGMAcwB/wFKAYsBywH/AUoBjQHOAf8BSgGOAdAB/wE/
+        AXQBvQH/ARsBTAGNAf8DSQGIDAADCwEPAqYBpwH/AdIBzAHLAf8BwQG5AbcB/wHMAcYBxQH/Ac8CygH/
+        Ac4ByAHGAf8BzQHHAcUB/wHOAskB/wHSAs8B/wHeAtwB/wHaAdQB1QH/AbEBnQGYAf8BpQGKAYMB/wGo
+        AY4BiAH/AaoBoAGeAf8DVwG3AzEBThQAAw8BFAMvAUoDLwFKAVMBVQFTAa0BZAGpAXYB+gFIAdkBZgH/
+        AT4B2gFhAf8BQwHeAWcB/wFXAeQBgwH/AYIB7AGfAf8BXwFhAV8B2wM0AVQBMAExATABTQMYASIcAAMr
+        AUIDUQGgAy8BSgFYAVwBWAHRATkBgAFlAfwBPgHAAVoB/wE2AcQBVwH/ASMBnwFbAf8BFAHAAeUB/wFM
+        Ae4C/wE8AeUB/AH/ATgB6AH9Af8BLQHkAf4B/wFOAXwBgQHwAV4CXwHVAUUB5AL/AUQCRQF8EAADTgGV
+        AVcBlAHVAf8BaAGlAeMB/wFsAagB5AH/AXABpgHhAf8BXgGPAcgB/wEzAYABsgH/AVMBlQHSAf8BWAGQ
+        AdEB/wFTAY8B0AH/AU8BjgHOAf8BTQGOAc0B/wFKAYwBzAH/AUoBjQHNAf8BSQGOAc8B/wFNAXgBogH6
+        A1oBxQMjATQEAAMYASEDuAH/Ac0BxgHFAf8BtwGuAawB/wG7AbQBsQH/AcYBwQG/Af8BzAHIAcYB/wHX
+        AdMB1AH/AeIB4AHfAf8B5gLiAf8B6QHjAeIB/wHiAdsB2gH/AeYC4QH/AckBvgG9Af8BpwGOAYcB/wGl
+        AYoBgwH/Aa8BmwGXAf8BogKeAf8DNwFaHAABUAFSAVABpAFtAZ4BbQH3AUQB0wFeAf8BMAHRAVAB/wEy
+        AdIBUgH/AUkB2gFoAf8BcQHlAZUB/wFWAVgBVgHBAwgBCyAAASECIgExAVUBbwFyAeoBQAHzAv8BVQJX
+        AbcBJwHgAfoB/wEgAdgB9gH/ARsByAHkAf8BFQHBAd0B/wEOAdcC/wEYAdAC/wFPAegB/AH/AUAB5wH8
+        Af8BPAHqAf0B/wEzAe8C/wE9Aj4BagQAAVoBvAHIAf0DUQGiDAADRgF+AWABngHfAf8BYwGgAeAB/wFm
+        AaEB3gH/AW4BowHfAf8BbgGlAd0B/wEzAa0B1wH/AQQBvgHhAf8BAwGvAdcB/wEoAaABzwH/AUoBlQHP
+        Af8BUwGRAc8B/wFWAY8BzwH/AVIBjwHPAf8BTQGOAc0B/wFLAY0BzAH/AUQBiQHLAf8BWwFxAY0B9gMZ
+        ASMEAAMCAQMDsgH/AegC5wH/AecB4wHkAf8B6gHnAegB/wHpAeUB5gH/AesB5QHmAf8B7gLnAf8B8wHu
+        Ae0B/wHtAuYB/wHXAcwBywH/AdEBxQHEAf8B1AHLAcoB/wHdAtYB/wHgAtsB/wG1AaEBngH/AaUBigGD
+        Af8BrgGaAZQB/wNbAcMcAAFQAVIBUAGkAW0BmwFtAfcBQQHNAVkB/wEpAckBRgH/ASkBywFHAf8BQQHS
+        AVwB/wFuAd8BjgH/AVcBWQFXAb8DCAELIAADSgGLAWgD/wFSAfwC/wFEA/8BNgH1Av8BLAHwAv8BJAHs
+        Av8BHQHmAv8BFAHcAv8BHQHcAv8BVQHqAf4B/wFEAecB/AH/AUEB7AH9Af8BMgHoAf4B/wFZAV4BXwHX
+        A1MBqgE6AeYC/wNIAYYEAAMXASADVgGxAVgBlwHaAf8BYAGdAd4B/wFlAaAB3gH/AXEBowHgAf8BWwGj
+        AdcB/wEKAbAB2AH/AQABuwHiAf8BAgHBAecB/wEAAb0B5QH/AQABvQHkAf8BAAG4AeAB/wEJAa4B2QH/
+        ASkBngHNAf8BRwGUAcwB/wFWAY8BzwH/AVMBjwHQAf8BRwGLAcwB/wM6AWAMAAMwAUsDVgG0AccBxgHF
+        Af8B4wHgAeEB/wHzAe0B7gH/Ae4B5wHoAf8B8gLuAf8B+AL1Af8B9ALxAf8B8QLsAf8B7AHoAecB/wHp
+        AeMB4gH/AeMB3QHcAf8B2ALUAf8B8QHrAewB/wHSAckByAH/AbEBngGZAf8DWwHDHAABTwFTAU8BpQFt
+        AZoBbQH3AT4ByAFTAf8BIwHCAT0B/wEiAcMBPQH/AT0BywFUAf8BbwHcAYwB/wFWAVkBVgG+AwgBCyQA
+        AT0CPgFqAUgCSQGHAUgCSQGHAVoBXgFaAdUBQwGMAV8B+wEiAZUBYAH/ARQBkQFVAf8BEgGQAVUB/wEh
+        AZMBZAH/AWEB5wHzAf8BVQHzAv8BRAHsAf0B/wE3AecB/QH/AS0B5gL/ASkB7gL/AUwBgAGLAfEDHAEo
+        BAADRwGBAVYBlwHbAf8BXAGcAd4B/wFkAZ8B3gH/AW4BoQHeAf8BSgGjAdQB/wEAAbEB2AH/AQABvQHl
+        Af8BAAG7AeQB/wEBAb8B5QH/AQABugHjAf8BAAG8AeUB/wEAAb0B5gH/AQABvQHlAf8BAAG8AeMB/wEA
+        AbQB2wH/ARcBpAHRAf8BNgGSAcoB/wNdAcoYAAMcAScDTAGQAb4CvQH/AdoB1wHZAf8B8gHtAe4B/wH4
+        AvUB/wHzAu4B/wHrAuQB/wHmAeAB3wH/AeIC2gH/AeQC3QH/AfQB7QHuAf8B+AHyAfQB/wHsAecB6QH/
+        AcEBvwHAAf8DNwFaHAABTwFTAU8BpQFtAZoBbQH3ATgBwgFLAf8BHAG7ATQB/wEbAbwBNAH/ATcBxgFN
+        Af8BbAHXAYcB/wFWAVkBVgG+AwgBCzAAAU8BUwFPAaUBbQGaAW0B9wE4AcIBSwH/ARwBuwE0Af8BGwG8
+        ATQB/wE3AcYBTQH/AU0BogFoAf8BXQHxAfcB/wFOAfsC/wE8Ae4C/wE0AfIC/wE+AZ4BpwH3AzEBTwgA
+        AwEBAgMeASsDUwGlAWIBgAGpAfoBKQGlAdMB/wEAAbcB3gH/AQABvAHkAf8BAAG6AeMB/wEMAcEB5gH/
+        AS8BxwHoAf8BGgHEAecB/wEDAcAB5gH/AQABvAHlAf8BAAG6AeMB/wEAAbsB5AH/AQABvAHlAf8BAAG8
+        AeUB/wEEAb4B6AH/AV8BYwFkAd0DFAEbHAADBwEJAzoBYANbAcYBzQHMAc0B/wHqAeYB6AH/AesB5QHn
+        Af8B6gHmAegB/wHgAd4B3wH/AdoB1wHZAf8ByQLIAf8DZQHhA1EBnAMoATwgAAFPAVMBTwGlAW4BmgGA
+        AfcBTQHGAV0B/wEyAb4BQwH/ATEBvgFDAf8BSgHHAVwB/wGIAdkBlQH/AVYBWQFWAb4DCAELMAABTwFT
+        AU8BpQFuAZoBgAH3AU0BxgFdAf8BMgG+AUMB/wExAb4BQwH/AUoBxwFcAf8BiAHZAZUB/wFaAV0BWgHK
+        AU4CTwGXAVUCVgGxAUkCSgGJAxoBJRQAAwIBAwFeAWIBZAHdAQABvwHpAf8BAAG7AeUB/wEAAboB4gH/
+        AR4BwwHlAf8BOgHFAeUB/wEwAcAB4wH/ATQBwgHkAf8BNwHGAecB/wEqAccB6QH/AREBwgHmAf8BAAG7
+        AeMB/wEAAbwB5gH/AQoBywH1Af8BIgHWAv8BiAHKAv8DWAHBAwcBCiQAAyEBMANOAZYDWgG9A04BmQM9
+        AWkDMAFLAxYBHiwAAU8BUwFPAaUBiAGhAYoB9wGIAdMBkgH/AWUBzAFwAf8BYwHNAXAB/wGGAdUBkQH/
+        AbMB5AG6Af8BVwFZAVcBvwMIAQswAAFPAVMBTwGlAYgBoQGKAfcBiAHTAZIB/wFlAcwBcAH/AWMBzQFw
+        Af8BhgHVAZEB/wGzAeQBugH/AVcBWQFXAb8DCAELIAADOgFgAVUBsgHzAf8BDgHRAf4B/wEfAdAB+QH/
+        AToB0QH1Af8BQgHNAfAB/wExAcQB6AH/ASwBwAHjAf8BKgG+AeEB/wEtAcAB5AH/ATIBwQHkAf8BNwHE
+        AeYB/wE9AdEB8wH/AT0B2AH7Af8BNwHbAv8BJwHXAf4B/wGHAccB+wH/AZMBxwL/A1ABnmwAAU8BUwFP
+        AaUBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwMI
+        AQswAAFPAVMBTwGlAVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7
+        AVYBWAFWAbsDCAELIAADVQGyAVABsgH1Af8BKAHWAf4B/wFNAdoB/gH/AUgB1gH9Af8BRQHVAfwB/wFG
+        AdUB/AH/AUAB0QH3Af8BOAHKAe8B/wEzAcUB6AH/ATcByQHsAf8BQwHTAfgB/wFLAdkB/gH/AUsB2gH9
+        Af8BTgHcAf4B/wFdAdUB/gH/AY8BxQH7Af8DVAGvAyYBOP8ABQADFgEfAzEBTgNIAYMDXAHNAUABtwHI
+        AfwBQAHVAf0B/wFAAdUB/QH/AUQB1QH8Af8BRwHWAf0B/wFHAdYB+wH/AUkB2AH8Af8BSAHYAf0B/wFD
+        AdkB/QH/AU8B0wH8Af8BawHHAfgB/wNWAbYDMAFL/wAdAAMgAS8DRwGCA1sBywFHAdQB+gH/AUMB1gH8
+        Af8BRAHYAf0B/wFDAdgB/QH/AUsBvAHaAf0BZQGHAZYB9AFjAWwBcwHqAzgBXf8AMQADKQE+A0cBgQNU
+        Aa4DVAGvAy4BRwMgAS4DGgElaAABQgFNAT4HAAE+AwABKAMAAVQDAAEoAwABAQEAAQEFAAHgAQEWAAP/
+        8QAK/wHwAQAK/wHwAQAB/wHfAf8B/gL/AYAD/wHwAQAB/wGPAf8B/AF/Af8BAAE/Av8B8AEAAf8BBwH/
+        AfgBPwH8AQABBwH+AQ8B8AEAAf4BAwH/AfABHwH4AQABBwH4AQcB8AEAAfwBAQH/AeABAQH4AQABBwHA
+        AQEB8AEAAfgBAAH/AcABAAH4AQABBwGAAQAB8AEAAfABAAF/AYABAAF4AQABBwIAATABAAHgAQABfwIA
+        AXgBAAEBAgABEAEAAfwBAQH+AQABAgFwAQABAQIAARABAAH8AQEB/gIAAUABAAEDAYABAAEQAQAB/AEB
+        Af8CAAFAAQABBwHgAQABEAEAAfwBAQH/AeABAAHAAQABAwH4AQABMAEAAfwBAQH/AeABAQHwAQABAQH/
+        AQEB8AEAAfwBAQH/AeABDwHwAQABAQL/AfABAAH8AQEB/wHgAQ8B8AEAAQEC/wHwAQAF/wHwAQABBwL/
+        AfABAAb/AQABHwL/AfABAAb/AeABPwL/AfABAAs=
 </value>
   </data>
+  <metadata name="featureToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>255, 18</value>
+  </metadata>
   <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>62</value>
   </metadata>

=== modified file 'WexInstaller/InstallWizard/InstallType.cs'
--- a/WexInstaller/InstallWizard/InstallType.cs	2011-03-10 18:30:35 +0000
+++ b/WexInstaller/InstallWizard/InstallType.cs	2011-03-18 10:29:04 +0000
@@ -1,129 +1,129 @@
 using System;
-using System.Collections.Generic;
-using System.ComponentModel;
 using System.Drawing;
-using System.Text;
+using System.IO;
 using System.Windows.Forms;
+
+using WexInstaller.Core;
 using WexInstaller.Properties;
-using WexInstaller.Core;
-using System.IO;
-using System.Resources;
+
+using MySQL.Utilities.SysUtils;
 
 namespace WexInstaller
 {
-    public partial class InstallType : InstallerPanel
-    {
-        private SetupType currentType;
-        private ProductCatalog catalog;
-
-        public InstallType()
-        {
-            InitializeComponent();
-            Caption = Resources.InstallTypeCaption;
-            installPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + Path.DirectorySeparatorChar + "MySQL";
-            nextOk = true;
-        }
-
-        public override void Activate()
-        {
-            base.Activate();
-
-            catalog = ProductManager.ActiveCatalog;
-            if (catalog == null)
-                catalog = ProductManager.Catalogs[0];
-
-            if (currentType == null)
-            {
-                int tabIndex = 1;
-                foreach (SetupType setupType in catalog.SetupTypes)
-                {
-                    RadioButton radio = new RadioButton();
-                    radio.AutoSize = true;
-                    radio.TabIndex = tabIndex++;
-                    radio.TabStop = true;
-                    radio.UseVisualStyleBackColor = true;
-                    radio.Text = setupType.Name;
-                    radio.Padding = new Padding(4);
-                    radio.Tag = setupType;
-                    radio.Font = new Font(Font, FontStyle.Bold);
-                    radio.Click += new EventHandler(setupTypeClicked);
-                    setupTypePanel.Controls.Add(radio);
-                }
-                (setupTypePanel.Controls[0] as RadioButton).PerformClick();
-            }
-        }
-
-        void setupTypeClicked(object sender, EventArgs e)
-        {
-            RadioButton rb = sender as RadioButton;
-            currentType =  rb.Tag as SetupType;
-            setupTypeDescription.Text = currentType.Description;
-
-            (ParentControl as InstallWizardControl).ShowFeatureSelection(currentType.Flag == (int)SetupTypeFlag.Custom);
-            SignalChange();
-        }
-
-        private void pathBrowseButton_Click(object sender, EventArgs e)
-        {
-            FolderBrowserDialog d = new FolderBrowserDialog();
-            if (d.ShowDialog() != DialogResult.OK) return;
-            installPath.Text = d.SelectedPath;
-            nextOk = true;
-            SignalChange();
-        }
-
-        public override bool Next()
-        {
-            // turn off installation of all products as we are redoing it here
-            ProductManager.SetGlobalProposedInstalled(false);
-
-            foreach (CatalogProduct product in catalog.Products)
-            {
-                product.ReferencedProduct.ProposedInstalled = currentType.Includes(product);
-            }
-
-            return base.Next();
-        }
-
-        private void installPath_TextChanged(object sender, EventArgs e)
-        {
-            nextOk = installPath.Text.Trim().Length > 0 && !invalidPath.Visible;
-            SignalChange();
-            string newPath = installPath.Text.Trim();
-
-            bool exists = Directory.Exists(newPath);
-            warningSign.Visible = exists;
-            pathExistsLabel.Visible = exists;
-
-            bool rooted = false;
-            try
-            {
-                rooted = Path.IsPathRooted(newPath) || newPath.Length == 0;
-            }
-            catch (ArgumentException)
-            {
-            }
-            abort.Visible = !rooted;
-            invalidPath.Visible = !rooted;
-
-            if (rooted && newPath.Length > 0)
-            {
-                string root = Directory.GetDirectoryRoot(newPath);
-                if (!newPath.StartsWith(root))
-                    newPath = root.Substring(0, 2) + newPath;
-                InstallerConfiguration.ProposedInstallationPath = installPath.Text.Trim();
-            }
-        }
-
-        private void InstallType_Paint(object sender, PaintEventArgs e)
-        {
-            Graphics gfx = e.Graphics;
-            Pen myPen = new Pen(Color.LightGray);
-            Point top = setupTypePanel.Location;
-            top.X += setupTypePanel.Width + 4;
-            Point bottom = top;
-            bottom.Y += setupTypePanel.Height;
-            gfx.DrawLine(myPen, top, bottom);
-        }
-    }
+  public partial class InstallType : InstallerPanel
+  {
+    private SetupType currentType;
+
+    public InstallType()
+    {
+      InitializeComponent();
+      Caption = Resources.InstallTypeCaption;
+      installPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + Path.DirectorySeparatorChar + "MySQL";
+      nextOk = true;
+    }
+
+    public override void Activate()
+    {
+      base.Activate();
+
+      if (currentType == null)
+      {
+        int tabIndex = 1;
+        foreach (SetupType setupType in ProductManager.ActiveCatalog.SetupTypes)
+        {
+          RadioButton radio = new RadioButton();
+          radio.AutoSize = true;
+          radio.TabIndex = tabIndex++;
+          radio.TabStop = true;
+          radio.UseVisualStyleBackColor = true;
+          radio.Text = setupType.Name;
+          radio.Padding = new Padding(4);
+          radio.Tag = setupType;
+          radio.Font = new Font(Font, FontStyle.Bold);
+          radio.Click += new EventHandler(setupTypeClicked);
+          setupTypePanel.Controls.Add(radio);
+        }
+        (setupTypePanel.Controls[0] as RadioButton).PerformClick();
+      }
+    }
+
+    void setupTypeClicked(object sender, EventArgs e)
+    {
+      RadioButton rb = sender as RadioButton;
+      currentType =  rb.Tag as SetupType;
+      setupTypeDescription.Text = currentType.Description;
+
+      (ParentControl as InstallWizardControl).ShowFeatureSelection(currentType.Flag == (int)SetupTypeFlag.Custom);
+      SignalChange();
+    }
+
+    private void pathBrowseButton_Click(object sender, EventArgs e)
+    {
+      FolderBrowserDialog d = new FolderBrowserDialog();
+      if (d.ShowDialog() != DialogResult.OK) return;
+      installPath.Text = d.SelectedPath;
+      nextOk = true;
+      SignalChange();
+    }
+
+    public override bool Next()
+    {
+      // Turn off installation of all products as we are redoing it here.
+      ProductManager.SetGlobalProposedInstalled(false);
+
+      // Reset the active catalog to our default if no customization was required.
+      if (currentType.Flag != (int)SetupTypeFlag.Custom)
+        ProductManager.ActiveCatalog = ProductManager.DefaultCatalog;
+
+      foreach (CatalogProduct product in ProductManager.ActiveCatalog.Products)
+        product.ReferencedProduct.ProposedInstalled = currentType.Includes(product);
+
+      return base.Next();
+    }
+
+    private void installPath_TextChanged(object sender, EventArgs e)
+    {
+      nextOk = installPath.Text.Trim().Length > 0 && !invalidPath.Visible;
+      SignalChange();
+      string newPath = installPath.Text.Trim();
+
+      bool exists = Directory.Exists(newPath);
+      warningSign.Visible = exists;
+      pathExistsLabel.Visible = exists;
+
+      bool rooted = false;
+      try
+      {
+        rooted = Path.IsPathRooted(newPath) || newPath.Length == 0;
+      }
+      catch (ArgumentException)
+      {
+      }
+      abort.Visible = !rooted;
+      invalidPath.Visible = !rooted;
+
+      if (rooted && newPath.Length > 0)
+      {
+        string root = Directory.GetDirectoryRoot(newPath);
+        if (!newPath.StartsWith(root))
+          newPath = root.Substring(0, 2) + newPath;
+        InstallerConfiguration.ProposedInstallationPath = installPath.Text.Trim();
+      }
+    }
+
+    /// <summary>
+    /// Draws a vertical separator line between the list of setup types and their
+    /// description text on the right.
+    /// </summary>
+    private void InstallType_Paint(object sender, PaintEventArgs e)
+    {
+      Graphics gfx = e.Graphics;
+      Pen myPen = new Pen(Color.LightGray);
+      Point top = setupTypeDescriptionLabel.Location;
+      top.X = setupTypePanel.Right;
+      Point bottom = top;
+      bottom.Y += setupTypePanel.Height;
+      gfx.DrawLine(myPen, top, bottom);
+    }
+  }
 }

=== modified file 'WexInstaller/Program.cs'
--- a/WexInstaller/Program.cs	2011-03-10 03:08:26 +0000
+++ b/WexInstaller/Program.cs	2011-03-18 10:29:04 +0000
@@ -1,85 +1,68 @@
 using System;
-using System.Collections.Generic;
 using System.Windows.Forms;
-using Mono.Options;
-using System.Runtime.InteropServices;
-using WexInstaller.Properties;
+
 using WexInstaller.Core;
-using System.Reflection;
-using System.IO;
-using System.Diagnostics;
 
 namespace WexInstaller
 {
-    public class Program
+  public class Program
+  {
+    /// <summary>
+    /// The main entry point for the application.
+    /// </summary>
+    [STAThread]
+    static void Main()
     {
-        /// <summary>
-        /// The main entry point for the application.
-        /// </summary>
-        [STAThread]
-        static void Main()
-        {
-            Logger.LogInformation("Installer starting up.");
-
-            InstallerConfiguration.Load();
-
-            Application.EnableVisualStyles();
-            Application.SetCompatibleTextRenderingDefault(false);
-
-            Logger.LogInformation("Loading product manifest");
-            ProductManager.Load();
-
-            Logger.LogInformation("Setting default catalog.");
-            string[] args = Environment.GetCommandLineArgs();
-            if (args.Length > 2)
-            {
-                ProductManager.DefaultCatalog = args[1]; // this should be the default catalog name
-            }
-            else
-            {
-                ProductManager.DefaultCatalog = null;
-            }
-
-            Application.Run(new MainForm());
-
-            InstallerConfiguration.Save();
-            Logger.LogInformation("Installer exit");
-        }
+      Logger.LogInformation("Installer starting up.");
+
+      InstallerConfiguration.Load();
+
+      Application.EnableVisualStyles();
+      Application.SetCompatibleTextRenderingDefault(false);
+
+      Logger.LogInformation("Loading product manifest");
+      ProductManager.Load();
+
+      Application.Run(new MainForm());
+
+      InstallerConfiguration.Save();
+      Logger.LogInformation("Installer exit");
+    }
 
 /*        static bool ProcessCommandLineArguments()
-        {
-            bool checkForUpdates = false;
-            bool showHelp = false;
-
-            string[] args = Environment.GetCommandLineArgs();
-            OptionSet options = new OptionSet();
-            options.Add(Resources.HelpOptions, Resources.HelpDescription, o => showHelp = true);
-            options.Add(Resources.CheckForUpdatesOptions, Resources.CheckForUpdatesDescription, o => checkForUpdates = true);
-            List<string> extra = options.Parse(Environment.GetCommandLineArgs());
-            if (showHelp)
-                ShowHelp(options);
-            else if (checkForUpdates)
-                CheckForUpdates();
-            else
-                return false;
-            return true;
-        }
-
-        static void ShowHelp(OptionSet options)
-        {
-            Console.WriteLine(Resources.AppName);
-            options.WriteOptionDescriptions(Console.Out);
-        }
-
-        public static void CheckForUpdates()
-        {
-            //DialogResult result = MessageBox.Show(Resources.UpdatesAreAvailable, Resources.UpdatesAreAvailableCaption, 
-            //    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
-            //if (result == DialogResult.Yes)
-            //{
-            //    // need to jump to the udpate form here
-            //    Program.FormManager.CurrentForm = new Overview(2);
-            //}
-        }*/
-    }
+    {
+        bool checkForUpdates = false;
+        bool showHelp = false;
+
+        string[] args = Environment.GetCommandLineArgs();
+        OptionSet options = new OptionSet();
+        options.Add(Resources.HelpOptions, Resources.HelpDescription, o => showHelp = true);
+        options.Add(Resources.CheckForUpdatesOptions, Resources.CheckForUpdatesDescription, o => checkForUpdates = true);
+        List<string> extra = options.Parse(Environment.GetCommandLineArgs());
+        if (showHelp)
+            ShowHelp(options);
+        else if (checkForUpdates)
+            CheckForUpdates();
+        else
+            return false;
+        return true;
+    }
+
+    static void ShowHelp(OptionSet options)
+    {
+        Console.WriteLine(Resources.AppName);
+        options.WriteOptionDescriptions(Console.Out);
+    }
+
+    public static void CheckForUpdates()
+    {
+        //DialogResult result = MessageBox.Show(Resources.UpdatesAreAvailable, Resources.UpdatesAreAvailableCaption, 
+        //    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+        //if (result == DialogResult.Yes)
+        //{
+        //    // need to jump to the udpate form here
+        //    Program.FormManager.CurrentForm = new Overview(2);
+        //}
+    }*/
+  }
 }

=== modified file 'WexInstaller/RemovePanels/RemoveComplete.cs'
--- a/WexInstaller/RemovePanels/RemoveComplete.cs	2011-03-10 18:30:35 +0000
+++ b/WexInstaller/RemovePanels/RemoveComplete.cs	2011-03-18 10:29:04 +0000
@@ -3,6 +3,7 @@
 using System.Diagnostics;
 using System.IO;
 using System.Windows.Forms;
+using System.Threading;
 
 using WexInstaller.Core;
 using WexInstaller.Properties;
@@ -77,9 +78,7 @@
             foreach (Product p in serverProducts)
             {
               string dataDirectory = p.GetInstalledProductRegistryKey("DataLocation");
-
-              if (!String.IsNullOrEmpty(dataDirectory) && Directory.Exists(dataDirectory))
-                Directory.Delete(dataDirectory, true);
+              DeleteDirectory(dataDirectory);
             }
           }
         }
@@ -106,5 +105,52 @@
 
       return base.Next();
     }
+
+    /// <summary>
+    /// Helper method to recursively remove a folder with some additional handling
+    /// not provided by Directory.Delete().
+    /// </summary>
+    /// <param name="target">The folder to remove (including all its content).</param>
+    /// <returns>True if removal was successful, otherwise false.</returns>
+    public static bool DeleteDirectory(string target)
+    {
+      bool result = !String.IsNullOrEmpty(target) && Directory.Exists(target);
+      if (!result)
+        return false;
+
+      string[] files = Directory.GetFiles(target);
+      string[] dirs = Directory.GetDirectories(target);
+
+      foreach (string file in files)
+      {
+        // In the case a file is set to read-only we would get an IO exception.
+        File.SetAttributes(file, FileAttributes.Normal);
+        File.Delete(file);
+      }
+
+      foreach (string dir in dirs)
+        DeleteDirectory(dir);
+
+      File.SetAttributes(target, FileAttributes.Normal);
+      try
+      {
+        Directory.Delete(target, false);
+      }
+      catch (DirectoryNotFoundException)
+      {
+        // Ignore. Folder might be removed outside of the application already.
+      }
+      catch (IOException)
+      {
+      	// Usually thrown if the folder is blocked.
+        if (Directory.GetCurrentDirectory().Equals(target, StringComparison.InvariantCultureIgnoreCase))
+          Directory.SetCurrentDirectory("..");
+        Thread.Sleep(0);
+        Directory.Delete(target, false);
+      }
+
+      return result;
+    }
+
   }
 }

=== modified file 'WexInstaller/WexInstaller.csproj'
--- a/WexInstaller/WexInstaller.csproj	2011-02-25 15:04:43 +0000
+++ b/WexInstaller/WexInstaller.csproj	2011-03-18 10:29:04 +0000
@@ -235,6 +235,9 @@
       <DependentUpon>FeatureBox.cs</DependentUpon>
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Controls\FeatureTreeView.resx">
+      <DependentUpon>FeatureTreeView.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Controls\RemoveControl.resx">
       <DependentUpon>RemoveControl.cs</DependentUpon>
       <SubType>Designer</SubType>

=== modified file 'installer-vs2010.sln'
--- a/installer-vs2010.sln	2011-03-10 03:08:26 +0000
+++ b/installer-vs2010.sln	2011-03-18 10:29:04 +0000
@@ -122,7 +122,6 @@
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Debug|x86.Build.0 = Debug|x86
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Any CPU.ActiveCfg = Release|x86
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Mixed Platforms.Build.0 = Release|x86
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Win32.ActiveCfg = Release|x86
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|x86.ActiveCfg = Release|x86
 		{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|x86.Build.0 = Release|x86
@@ -146,7 +145,6 @@
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Debug|x86.Build.0 = Debug|x86
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Any CPU.ActiveCfg = Release|x86
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Mixed Platforms.Build.0 = Release|x86
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Win32.ActiveCfg = Release|x86
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|x86.ActiveCfg = Release|x86
 		{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|x86.Build.0 = Release|x86
@@ -193,7 +191,6 @@
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Debug|x86.Build.0 = Debug|x86
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Any CPU.ActiveCfg = Release|x86
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Mixed Platforms.Build.0 = Release|x86
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Win32.ActiveCfg = Release|x86
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|x86.ActiveCfg = Release|x86
 		{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|x86.Build.0 = Release|x86

Attachment: [text/bzr-bundle] bzr/mike.lischke@oracle.com-20110318102904-q1xhttrx7ubu91rn.bundle
Thread
bzr commit into wex-installer-1.0 branch (mike.lischke:371) Mike Lischke18 Mar