/// <summary>
        /// Collect all Windows form control's event information and dump it.
        /// </summary>
        /// <returns>Iteration of dumped string</returns>
        public static IEnumerable <string> DumpControlEvents()
        {
            foreach (Type controlType in typeof(System.Windows.Forms.Control).Assembly.GetTypes())
            {
                if (controlType.IsAbstract)
                {
                    continue;
                }

                if (!controlType.Equals(typeof(System.Windows.Forms.Control)) &&
                    !controlType.IsSubclassOf(typeof(System.Windows.Forms.Control)))
                {
                    continue;
                }

                if (controlType.Equals(typeof(System.Windows.Forms.WebBrowser)) &&
                    System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.STA)
                {
                    continue;
                }

                ConstructorInfo ci = controlType.GetConstructor(Type.EmptyTypes);
                if ((ci == null) ||
                    (!ci.IsPublic))
                {
                    continue;
                }

                EventRelatedFieldInfoContainer container = new EventRelatedFieldInfoContainer(controlType);

                yield return($"Control Type : {container.ControlType.Name}{Environment.NewLine}");

                foreach (EventRelatedFieldInfo info in container.GetEventRelatedFieldInfos())
                {
                    yield return(info.GetInformationString());
                }

                yield return(Environment.NewLine);
            }
        }
        private static void InitializeControl(Control targetControl, Control originalControl, bool duplicating)
        {
            #region Handle Control.Controls property.

            // List child controls to move or to duplicate.
            List <Control> childControlList = new List <Control>();
            foreach (Control childControl in originalControl.Controls)
            {
                childControlList.Add(childControl);
            }

            foreach (Control childControl in childControlList)
            {
                if (duplicating)
                {
                    Control duplicatedChildControl = DuplicateControl(childControl);
                    targetControl.Controls.Add(duplicatedChildControl);
                }
                else
                {
                    originalControl.Controls.Remove(childControl);
                    targetControl.Controls.Add(childControl);
                }
            }

            #endregion

            #region Handle other properties.

            // Iterate public and readable properties from originalControl.
            foreach (PropertyInfo originalPi in originalControl.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty))
            {
                if (!originalPi.CanRead)
                {
                    continue;
                }

                // Controls property is already handled.
                if (originalPi.Name == nameof(Control.Controls))
                {
                    continue;
                }

                // Parent property must not be changed here.
                if (originalPi.Name == nameof(Control.Parent))
                {
                    continue;
                }

                // Except Name property, not browsable properties are ignored.
                BrowsableAttribute originalBrowsable = originalPi.GetCustomAttribute <BrowsableAttribute>(true);
                if ((originalBrowsable != null) && !originalBrowsable.Browsable)
                {
                    if (originalPi.Name != nameof(Control.Name))
                    {
                        continue;
                    }
                }

                // Get corresponding public and writable property from targetControl.
                // Notice that the type of targetControl may be derived from the type of originalControl.
                // This is allowed when calling ReplaceControl method.
                PropertyInfo targetPi = GetPublicSetProperty(originalPi.Name, targetControl.GetType());
                if ((targetPi == null) || !targetPi.CanWrite || !targetPi.PropertyType.IsAssignableFrom(originalPi.PropertyType))
                {
                    continue;
                }

                // BrowsableAttribute also may be overwritten.
                BrowsableAttribute targetBrowsable = originalPi.GetCustomAttribute <BrowsableAttribute>(true);
                if ((targetBrowsable != null) && !targetBrowsable.Browsable)
                {
                    continue;
                }

                object value = originalPi.GetValue(originalControl, null);
                targetPi.SetValue(targetControl, value, null);
            }

            #endregion

            #region Handle events.

            EventRelatedFieldInfoContainer infoContainer = new EventRelatedFieldInfoContainer(originalControl.GetType());

            foreach (EventRelatedFieldInfo info in infoContainer.GetEventRelatedFieldInfos())
            {
                if (duplicating)
                {
                    info.CopyDelegate(targetControl, originalControl);
                }
                else
                {
                    info.MoveDelegate(targetControl, originalControl);
                }
            }

            #endregion

            // Duplicated control's Visible property tends to become false. Force to set true by default.
            targetControl.Visible = true;
        }