/// <summary>
        /// Initializes a new instance of the Expando class with default settings
        /// </summary>
        public Expando()
            : base()
        {
            // This call is required by the Windows.Forms Form Designer.
            this.components = new System.ComponentModel.Container();

            // set control styles
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.TabStop = true;

            // get the system theme settings
            this.systemSettings = ThemeManager.GetSystemExplorerBarSettings();

            this.customSettings = new ExpandoInfo();
            this.customSettings.Expando = this;
            this.customSettings.SetDefaultEmptyValues();

            this.customHeaderSettings = new HeaderInfo();
            this.customHeaderSettings.Expando = this;
            this.customHeaderSettings.SetDefaultEmptyValues();

            this.BackColor = this.systemSettings.Expando.NormalBackColor;

            // the height of the Expando in the expanded state
            this.expandedHeight = 100;

            // animation
            this.animate = false;
            this.animatingFade = false;
            this.animatingSlide = false;
            this.animationImage = null;
            this.slideEndHeight = -1;
            this.animationHelper = null;
            this.fadeHeights = new int[AnimationHelper.NumAnimationFrames];

            // size
            this.Size = new Size(this.systemSettings.Header.BackImageWidth, this.expandedHeight);
            this.titleBarHeight = this.systemSettings.Header.BackImageHeight;
            this.headerHeight = this.titleBarHeight;
            this.oldWidth = this.Width;

            // start expanded
            this.collapsed = false;

            // not a special group
            this.specialGroup = false;

            // unfocused titlebar
            this.focusState = FocusStates.None;

            // no title image
            this.titleImage = null;
            this.watermark = null;

            this.Font = new Font(this.TitleFont.Name, 8.25f, FontStyle.Regular);

            // don't get the Expando to layout its items itself
            this.autoLayout = false;

            // don't know which TaskPane we belong to
            this.taskpane = null;

            // internal list of items
            this.itemList = new ItemCollection(this);
            this.hiddenControls = new ArrayList();

            // initialise the dummyPanel
            this.dummyPanel = new AnimationPanel();
            this.dummyPanel.Size = this.Size;
            this.dummyPanel.Location = new Point(-1000, 0);

            this.canCollapse = true;

            this.showFocusCues = false;
            this.useDefaultTabHandling = true;

            this.CalcAnimationHeights();

            this.slideAnimationBatched = false;

            this.dragging = false;
            this.dragStart = Point.Empty;

            this.beginUpdateCount = 0;

            this.initialising = false;
            this.layout = false;
        }
        /// <summary>
        /// Forces the TaskPane and all it's Expandos to use the 
        /// current system theme
        /// </summary>
        public void UseDefaultTheme()
        {
            this.customTheme = false;
            this.classicTheme = false;

            ExplorerBarInfo settings = ThemeManager.GetSystemExplorerBarSettings();

            this.systemSettings.Dispose();
            this.systemSettings = null;

            this.SystemSettings = settings;
        }
        /// <summary> 
        /// Releases the unmanaged resources used by the Expando and 
        /// optionally releases the managed resources
        /// </summary>
        /// <param name="disposing">True to release both managed and unmanaged 
        /// resources; false to release only unmanaged resources</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }

                if (this.systemSettings != null)
                {
                    this.systemSettings.Dispose();
                    this.systemSettings = null;
                }

                if (this.animationHelper != null)
                {
                    this.animationHelper.Dispose();
                    this.animationHelper = null;
                }
            }

            base.Dispose(disposing);
        }
        /// <summary>
        /// Initializes a new instance of the TaskPane class with default settings
        /// </summary>
        public TaskPane()
        {
            // This call is required by the Windows.Forms Form Designer.
            components = new System.ComponentModel.Container();

            // set control styles
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            this.expandoCollection = new TaskPane.ExpandoCollection(this);

            // get the system theme settings
            this.systemSettings = ThemeManager.GetSystemExplorerBarSettings();

            this.customSettings = new TaskPaneInfo();
            this.customSettings.TaskPane = this;
            this.customSettings.SetDefaultEmptyValues();

            this.BackColor = this.systemSettings.TaskPane.GradientStartColor;
            this.BackgroundImage = this.BackImage;

            this.classicTheme = false;
            this.customTheme = false;

            // size
            int width = (this.systemSettings.TaskPane.Padding.Left +
                this.systemSettings.TaskPane.Padding.Right +
                this.systemSettings.Header.BackImageWidth);
            int height = width;
            this.Size = new Size(width, height);

            // setup sutoscrolling
            this.AutoScroll = false;
            this.AutoScrollMargin = new Size(this.systemSettings.TaskPane.Padding.Right,
                this.systemSettings.TaskPane.Padding.Bottom);

            // Listen for changes to the parent
            this.ParentChanged += new EventHandler(this.OnParentChanged);

            this.allowExpandoDragging = false;
            this.dropPoint = Point.Empty;
            this.dropIndicatorColor = Color.Red;

            this.beginUpdateCount = 0;

            this.initialising = false;
            this.layout = false;
        }
        /// <summary>
        /// Forces the TaskPane and all it's Expandos to use the 
        /// specified theme
        /// </summary>
        /// <param name="stylePath">The path to the custom 
        /// shellstyle.dll to use</param>
        public void UseCustomTheme(string stylePath)
        {
            this.customTheme = true;
            this.classicTheme = false;

            ExplorerBarInfo settings = ThemeManager.GetSystemExplorerBarSettings(stylePath);

            this.systemSettings.Dispose();
            this.systemSettings = null;

            this.SystemSettings = settings;
        }
        /// <summary>
        /// Initializes a new instance of the TaskItem class with default settings
        /// </summary>
        public TaskItem()
            : base()
        {
            // set control styles
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.Selectable, true);

            this.TabStop = true;

            this.BackColor = Color.Transparent;

            // get the system theme settings
            this.systemSettings = ThemeManager.GetSystemExplorerBarSettings();

            this.customSettings = new TaskItemInfo();
            this.customSettings.TaskItem = this;
            this.customSettings.SetDefaultEmptyValues();

            // preferred size
            this.preferredWidth = -1;
            this.preferredHeight = -1;

            // unfocused item
            this.focusState = FocusStates.None;

            this.Cursor = Cursors.Hand;

            this.textRect = new Rectangle();
            this.TextAlign = ContentAlignment.TopLeft;

            this.showFocusCues = false;
            this.useGdiText = false;

            this.InitStringFormat();
            this.InitDrawTextFlags();
        }
        /// <summary> 
        /// Raises the SystemColorsChanged event
        /// </summary>
        /// <param name="e">An EventArgs that contains the event data</param>
        protected override void OnSystemColorsChanged(EventArgs e)
        {
            base.OnSystemColorsChanged(e);

            // don't go any further if we are explicitly using
            // the classic or a custom theme
            if (this.classicTheme || this.customTheme)
            {
                return;
            }

            this.SuspendLayout();

            // get rid of the current system theme info
            this.systemSettings.Dispose();
            this.systemSettings = null;

            // get a new system theme info for the new theme
            this.systemSettings = ThemeManager.GetSystemExplorerBarSettings();

            this.BackgroundImage = this.BackImage;

            // update the system settings for each expando
            foreach (Control control in this.Controls)
            {
                if (control is Expando)
                {
                    Expando expando = (Expando) control;

                    expando.SystemSettings = this.systemSettings;
                }
            }

            // update the layout of the controls
            this.DoLayout();

            this.ResumeLayout(true);
        }
        /// <summary>
        /// Gets the System defined settings for the ExplorerBar according
        /// to the current System theme
        /// </summary>
        /// <param name="useClassicTheme">Specifies whether the current system theme 
        /// should be ignored and return unthemed settings</param>
        /// <returns>An ExplorerBarInfo object that contains the System defined 
        /// settings for the ExplorerBar according to the current System theme</returns>
        public static ExplorerBarInfo GetSystemExplorerBarSettings(bool useClassicTheme)
        {
            // check if we can return the cached theme
            // note: caching a classic theme seems to cause a few
            //       problems i haven't been able to resolve, so
            //       for the moment always return a new
            //       ExplorerBarInfo if useClassicTheme is true
            if (currentShellStyle != null && !useClassicTheme)
            {
                if (currentShellStyle.ShellStylePath != null && currentShellStyle.ShellStylePath.Equals(GetShellStylePath()))
                {
                    return currentShellStyle;
                }
            }

            ExplorerBarInfo systemTheme;

            // check if we are using themes.  if so, load up the
            // appropriate shellstyle.dll
            if (!useClassicTheme && UxTheme.AppThemed && LoadShellStyleDll())
            {
                try
                {
                    // get the uifile contained in the shellstyle.dll
                    // and get ready to parse it
                    Parser parser = new Parser(GetResourceUIFile());

                    // let the parser do its stuff
                    systemTheme = parser.Parse();
                    systemTheme.SetOfficialTheme(true);
                    systemTheme.ShellStylePath = GetShellStylePath();
                }
                catch
                {
                    // something went wrong, so use default settings
                    systemTheme = new ExplorerBarInfo();
                    systemTheme.UseClassicTheme();
                    systemTheme.SetOfficialTheme(true);

                    // add non-themed arrows as the ExplorerBar will
                    // look funny without them.
                    systemTheme.SetUnthemedArrowImages();
                }
                finally
                {
                    // unload the shellstyle.dll
                    FreeShellStyleDll();
                }
            }
            else
            {
                // no themes available, so use default settings
                systemTheme = new ExplorerBarInfo();
                systemTheme.UseClassicTheme();
                systemTheme.SetOfficialTheme(true);

                // add non-themed arrows as the ExplorerBar will
                // look funny without them.
                systemTheme.SetUnthemedArrowImages();
            }

            // cache the theme
            currentShellStyle = systemTheme;

            return systemTheme;
        }
        /// <summary>
        /// Gets the System defined settings for the ExplorerBar specified
        /// by the shellstyle.dll at the specified path
        /// </summary>
        /// <param name="stylePath">The path to the shellstyle.dll</param>
        /// <returns>An ExplorerBarInfo object that contains the settings for 
        /// the ExplorerBar specified by the shellstyle.dll at the specified path</returns>
        public static ExplorerBarInfo GetSystemExplorerBarSettings(string stylePath)
        {
            // check if we can return the cached theme
            if (currentShellStyle != null)
            {
                if (!currentShellStyle.ClassicTheme && currentShellStyle.ShellStylePath != null && currentShellStyle.ShellStylePath.Equals(stylePath))
                {
                    return currentShellStyle;
                }
            }

            ExplorerBarInfo systemTheme;

            // attampt to load the specified shellstyle.dll
            if (LoadShellStyleDll(stylePath))
            {
                try
                {
                    // get the uifile contained in the shellstyle.dll
                    // and get ready to parse it
                    Parser parser = new Parser(GetResourceUIFile());

                    // let the parser do its stuff
                    systemTheme = parser.Parse();
                    systemTheme.SetOfficialTheme(false);
                    systemTheme.ShellStylePath = stylePath;
                }
                catch
                {
                    // something went wrong, so try to use current system theme
                    systemTheme = GetSystemExplorerBarSettings();
                }
                finally
                {
                    // unload the shellstyle.dll
                    FreeShellStyleDll();
                }
            }
            else
            {
                // no themes available, so use default settings
                systemTheme = new ExplorerBarInfo();
                systemTheme.UseClassicTheme();
                systemTheme.SetOfficialTheme(true);

                // add non-themed arrows as the ExplorerBar will
                // look funny without them.
                systemTheme.SetUnthemedArrowImages();
            }

            // cache the theme
            currentShellStyle = systemTheme;

            return systemTheme;
        }
        /// <summary>
        /// Parses the UIFILE
        /// </summary>
        /// <returns>An ExplorerBarInfo object that contains the system 
        /// settings defined in the UIFILE</returns>
        public ExplorerBarInfo Parse()
        {
            this.info = new ExplorerBarInfo();

            string token = null;

            // keep going till we run out of tokens
            while (this.tokenizer.HasMoreTokens())
            {
                // get the next token
                token = this.tokenizer.NextToken();

                // is the token the start of a style section
                if (token.Equals("style"))
                {
                    // work out which style section it is
                    style = GetStyle(token);
                }
                    // is the token the end of a style section
                else if (token.Equals("/style"))
                {
                    // reset the style
                    style = UNKNOWN;
                }
                    // is the token the start of a property section in a known style
                else if (style != UNKNOWN && IsSection(token))
                {
                    // work out which property section it is
                    section = GetSection(token);
                }
                    // is the token a property that belongs to a known property
                    // section and style
                else if (style != UNKNOWN && section != UNKNOWN && IsProperty(token))
                {
                    // get the property
                    property = GetPropertyType(token);
                    ExtractProperty();
                }
            }

            return info;
        }
            /// <summary>
            /// Returns an ExplorerBarInfo that contains the deserialized ExplorerBarInfoSurrogate data
            /// </summary>
            /// <returns>An ExplorerBarInfo that contains the deserialized ExplorerBarInfoSurrogate data</returns>
            public ExplorerBarInfo Save()
            {
                ExplorerBarInfo explorerBarInfo = new ExplorerBarInfo();

                explorerBarInfo.TaskPane = this.TaskPaneInfoSurrogate.Save();
                explorerBarInfo.TaskItem = this.TaskItemInfoSurrogate.Save();
                explorerBarInfo.Expando = this.ExpandoInfoSurrogate.Save();
                explorerBarInfo.Header = this.HeaderInfoSurrogate.Save();

                return explorerBarInfo;
            }
            /// <summary>
            /// Populates the ExplorerBarInfoSurrogate with data that is to be 
            /// serialized from the specified ExplorerBarInfo
            /// </summary>
            /// <param name="explorerBarInfo">The ExplorerBarInfo that contains the data 
            /// to be serialized</param>
            public void Load(ExplorerBarInfo explorerBarInfo)
            {
                this.TaskPaneInfoSurrogate = new TaskPaneInfo.TaskPaneInfoSurrogate();
                this.TaskPaneInfoSurrogate.Load(explorerBarInfo.TaskPane);

                this.TaskItemInfoSurrogate = new TaskItemInfo.TaskItemInfoSurrogate();
                this.TaskItemInfoSurrogate.Load(explorerBarInfo.TaskItem);

                this.ExpandoInfoSurrogate = new ExpandoInfo.ExpandoInfoSurrogate();
                this.ExpandoInfoSurrogate.Load(explorerBarInfo.Expando);

                this.HeaderInfoSurrogate = new HeaderInfo.HeaderInfoSurrogate();
                this.HeaderInfoSurrogate.Load(explorerBarInfo.Header);
            }