/// <summary>
        /// Initialize a new instance of the ViewLayoutRibbonGroups class.
        /// </summary>
        /// <param name="ribbon">Owning ribbon control instance.</param>
        /// <param name="ribbonTab">RibbonTab to organize groups.</param>
        /// <param name="needPaint">Delegate for notifying paint requests.</param>
        public ViewLayoutRibbonGroups(KryptonRibbon ribbon,
                                      KryptonRibbonTab ribbonTab,
                                      NeedPaintHandler needPaint)
        {
            Debug.Assert(ribbon != null);
            Debug.Assert(ribbonTab != null);
            Debug.Assert(needPaint != null);

            // Cache references
            _ribbon    = ribbon;
            _ribbonTab = ribbonTab;
            _needPaint = needPaint;

            // Create initial lookup table
            _groupToView = new GroupToView();

            // Create cache of group separator elements
            _groupSepCache = new ViewDrawRibbonGroupSepList();
        }
        private void SyncChildrenToRibbonGroups()
        {
            // Remove all child elements
            Clear();

            // Create a new lookup that reflects any changes in groups
            GroupToView regenerate = new GroupToView();

            // Make sure we have a view element to match each group
            foreach (KryptonRibbonGroup group in _ribbonTab.Groups)
            {
                ViewDrawRibbonGroup view = null;

                // Get the currently cached view for the group
                if (_groupToView.ContainsKey(group))
                {
                    view = _groupToView[group];
                }

                // If a new group, create a view for it now
                if (view == null)
                {
                    view = new ViewDrawRibbonGroup(_ribbon, group, _needPaint);
                }

                // Add to the lookup for future reference
                regenerate.Add(group, view);
            }

            if (_groupSepCache.Count < _ribbonTab.Groups.Count)
            {
                for (int i = _groupSepCache.Count; i < _ribbonTab.Groups.Count; i++)
                {
                    _groupSepCache.Add(new ViewLayoutRibbonSeparator(0, true));
                }
            }

            // Update size of all separators to match ribbon shape
            Size sepSize = SeparatorSize;

            foreach (ViewLayoutRibbonSeparator sep in _groupSepCache)
            {
                sep.SeparatorSize = sepSize;
            }

            // We ignore the first separator
            bool ignoreSep = true;

            // Add child elements appropriate for each ribbon group
            for (int i = 0; i < _ribbonTab.Groups.Count; i++)
            {
                KryptonRibbonGroup ribbonGroup = _ribbonTab.Groups[i];

                // Only make the separator visible if the group is and not the first sep
                bool groupVisible = (_ribbon.InDesignHelperMode || ribbonGroup.Visible);
                _groupSepCache[i].Visible       = groupVisible && !ignoreSep;
                regenerate[ribbonGroup].Visible = groupVisible;

                // Only add a separator for the second group onwards
                if (groupVisible && ignoreSep)
                {
                    ignoreSep = false;
                }

                Add(_groupSepCache[i]);
                Add(regenerate[ribbonGroup]);

                // Remove entries we still are using
                if (_groupToView.ContainsKey(ribbonGroup))
                {
                    _groupToView.Remove(ribbonGroup);
                }
            }

            // When in design time help mode
            if (_ribbon.InDesignHelperMode)
            {
                // Create the design time 'Add Group' first time it is needed
                if (_viewAddGroup == null)
                {
                    _viewAddGroup = new ViewDrawRibbonDesignGroup(_ribbon, _needPaint);
                }

                // Always add at end of the list of groups
                Add(_viewAddGroup);
            }

            // Dispose of views no longer required
            foreach (ViewDrawRibbonGroup group in _groupToView.Values)
            {
                group.Dispose();
            }

            // No longer need the old lookup
            _groupToView = regenerate;
        }