/// <summary>
        ///
        /// </summary>
        /// <param name="guiControlType">The type of control you wish to update.</param>
        /// <returns>A IDictionary<XMLSkinAttribute, MemberInfo> which contains the MemberInfo objects for every
        /// updatable field, indexed by their corresponding Xml Element name. </returns>
        private static IDictionary <XMLSkinAttribute, MemberInfo> GetAttributesToUpdate(Type guiControlType)
        {
            // Lazy Initializiation...
            IDictionary <XMLSkinAttribute, MemberInfo> getAttributesToUpdate = null;

            if (m_reflectionCacheByControlTypeAttr.TryGetValue(guiControlType, out getAttributesToUpdate))
            {
                return(getAttributesToUpdate);
            }

            IDictionary <XMLSkinAttribute, MemberInfo> membersTable = new Dictionary <XMLSkinAttribute, MemberInfo>();

            MemberInfo[] allMembers = guiControlType.GetMembers(
                BindingFlags.Instance
                | BindingFlags.NonPublic
                | BindingFlags.FlattenHierarchy
                | BindingFlags.Public);

            foreach (MemberInfo member in allMembers)
            {
                if (member.IsDefined(typeof(XMLSkinAttribute), false))
                {
                    XMLSkinAttribute atrb = (XMLSkinAttribute)
                                            member.GetCustomAttributes(typeof(XMLSkinAttribute), false)[0];

                    membersTable[atrb] = member;
                }
            }
            m_reflectionCacheByControlTypeAttr[guiControlType] = membersTable;
            return(membersTable);
        }
        private static void UpdateControlWithXmlData(GUIControl control, Type controlType, XmlNode pControlNode,
                                                     IDictionary <string, string> defines, string filename)
        {
            List <int> vecInfo = new List <int>();
            IDictionary <XMLSkinAttribute, MemberInfo> attributesThatCanBeUpdates = GetAttributesToUpdate(controlType);

            if (attributesThatCanBeUpdates != null)
            {
                var nodeDic = getNodes(pControlNode);
                foreach (KeyValuePair <XMLSkinAttribute, MemberInfo> en in attributesThatCanBeUpdates)
                {
                    XMLSkinAttribute xmlAttr = (XMLSkinAttribute)en.Key;
                    MemberInfo       correspondingMemberAttr = en.Value as MemberInfo;
                    //XmlNode elementNode = pControlNode.SelectSingleNode(xmlAttr.XmlElementName);
                    //XmlNode elementNode = pControlNode.SelectSingleNodeFast(xmlAttr.XmlElementName);
                    XmlNode elementNode;
                    //if (elementNode != null)
                    if (nodeDic.TryGetValue(xmlAttr.XmlElementName, out elementNode))
                    {
                        XmlNode attribNode = elementNode.Attributes.GetNamedItem(xmlAttr.XmlAttributeName);
                        if (attribNode != null)
                        {
                            if (correspondingMemberAttr != null)
                            {
                                string text = attribNode.Value;

                                // Window defines (passed in) override references defines (cached).
                                if (text.Length > 0 && text[0] == '#')
                                {
                                    string foundDefine = null;
                                    if (defines.TryGetValue(text, out foundDefine))
                                    {
                                        text = foundDefine;
                                    }
                                    else
                                    {
                                        if (_cachedDefines.TryGetValue(text, out foundDefine))
                                        {
                                            text = foundDefine;
                                        }
                                    }
                                }

                                object newValue = null;

                                if (correspondingMemberAttr.MemberType == MemberTypes.Field)
                                {
                                    newValue = ConvertXmlStringToObject(xmlAttr.XmlAttributeName, text,
                                                                        ((FieldInfo)correspondingMemberAttr).FieldType);
                                }
                                else if (correspondingMemberAttr.MemberType == MemberTypes.Property)
                                {
                                    newValue = ConvertXmlStringToObject(xmlAttr.XmlAttributeName, text,
                                                                        ((PropertyInfo)correspondingMemberAttr).PropertyType);
                                }

                                try
                                {
                                    if (correspondingMemberAttr.MemberType == MemberTypes.Field)
                                    {
                                        ((FieldInfo)correspondingMemberAttr).SetValue(control, newValue);
                                    }
                                    else if (correspondingMemberAttr.MemberType == MemberTypes.Property)
                                    {
                                        ((PropertyInfo)correspondingMemberAttr).SetValue(control, newValue, null);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Log.Info("Couldn't place {0}, which is {1} in {2}. Exception:{3}",
                                             newValue, newValue.GetType(), correspondingMemberAttr, e);
                                }
                            }
                            else
                            {
                                if (char.IsUpper(xmlAttr.XmlAttributeName[0]))
                                {
                                    PropertyInfo propertyInfo;

                                    if (xmlAttr.XmlAttributeName.IndexOf('.') != -1)
                                    {
                                        propertyInfo = controlType.GetProperty(xmlAttr.XmlAttributeName.Split('.')[1]);
                                    }
                                    else
                                    {
                                        propertyInfo = controlType.GetProperty(xmlAttr.XmlAttributeName);
                                    }

                                    if (propertyInfo == null)
                                    {
                                        Log.Info(
                                            "GUIControlFactory.UpdateControlWithXmlData: '{0}' does not contain a definition for '{1}'",
                                            controlType, xmlAttr.XmlAttributeName);
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            IDictionary <string, MemberInfo> membersThatCanBeUpdated = GetMembersToUpdate(controlType);
            List <VisualEffect> animations      = new List <VisualEffect>();
            List <VisualEffect> thumbAnimations = new List <VisualEffect>();
            XmlNodeList         childNodes      = pControlNode.ChildNodes;
            bool hasVisiblecondition            = false;

            foreach (XmlNode element in childNodes)
            {
                if (element.Name == "visible")
                {
                    if (element.InnerText != null)
                    {
                        hasVisiblecondition = true;
                        if (element.InnerText != "yes" && element.InnerText != "no")
                        {
                            if (element.InnerText.Length != 0)
                            {
                                int  iVisibleCondition = 0;
                                bool allowHiddenFocus  = false;
                                //Add parent's visible condition in addition to ours
                                XmlNode parentNode = pControlNode.ParentNode;
                                if (IsGroupControl(parentNode))
                                {
                                    string parentVisiblecondition = GetVisibleConditionXML(parentNode);
                                    if (!string.IsNullOrEmpty(parentVisiblecondition) && parentVisiblecondition != "yes" &&
                                        parentVisiblecondition != "no")
                                    {
                                        element.InnerText += "+[" + parentVisiblecondition + "]";
                                    }
                                }
                                GetConditionalVisibility(element, control, ref iVisibleCondition, ref allowHiddenFocus);
                                control.SetVisibleCondition(iVisibleCondition, allowHiddenFocus);
                                continue;
                            }
                        }
                    }
                }
                if (element.Name == "animation")
                {
                    VisualEffect effect = new VisualEffect();
                    if (effect.Create(element))
                    {
                        if (effect.AnimationType == AnimationType.VisibleChange)
                        {
                            effect.AnimationType = AnimationType.Visible;
                            //if (effect.IsReversible)
                            {
                                VisualEffect effect2 = (VisualEffect)effect.CloneReverse();
                                effect2.AnimationType = AnimationType.Hidden;
                                //animations.Add(effect);
                                animations.Add(effect2);
                                //continue;
                            }
                        }
                        animations.Add(effect);
                        continue;
                    }
                }
                if (element.Name == "thumbAnimation")
                {
                    VisualEffect effect = new VisualEffect();
                    if (effect.Create(element))
                    {
                        thumbAnimations.Add(effect);
                        continue;
                    }
                }
                if (element.Name == "info")
                {
                    List <string> infoList = new List <string>();
                    if (GetMultipleString(element, "info", ref infoList))
                    {
                        vecInfo.Clear();
                        for (int i = 0; i < infoList.Count; i++)
                        {
                            int infoId = GUIInfoManager.TranslateString(infoList[i]);
                            if (infoId != 0)
                            {
                                vecInfo.Add(infoId);
                            }
                        }
                    }
                    control.Info = vecInfo;
                }
                MemberInfo correspondingMember = null;
                membersThatCanBeUpdated.TryGetValue(element.Name, out correspondingMember);

                if (correspondingMember != null)
                {
                    string text = element.InnerText;

                    // Window defines (passed in) override references defines (cached).
                    if (text.Length > 0 && text[0] == '#')
                    {
                        string foundDefine = null;

                        if (defines.TryGetValue(text, out foundDefine))
                        {
                            text = foundDefine;
                        }
                        else
                        {
                            if (_cachedDefines.TryGetValue(text, out foundDefine))
                            {
                                text = foundDefine;
                            }
                        }
                    }

                    object newValue = null;

                    if (correspondingMember.MemberType == MemberTypes.Field)
                    {
                        newValue = ConvertXmlStringToObject(element.Name, text, ((FieldInfo)correspondingMember).FieldType);
                    }
                    else if (correspondingMember.MemberType == MemberTypes.Property)
                    {
                        newValue = ConvertXmlStringToObject(element.Name, text, ((PropertyInfo)correspondingMember).PropertyType);
                    }

                    try
                    {
                        if (correspondingMember.MemberType == MemberTypes.Field)
                        {
                            ((FieldInfo)correspondingMember).SetValue(control, newValue);
                        }
                        else if (correspondingMember.MemberType == MemberTypes.Property)
                        {
                            ((PropertyInfo)correspondingMember).SetValue(control, newValue, null);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Info("Couldn't place {0}, which is {1} in {2}. Exception:{3}",
                                 newValue, newValue.GetType(), correspondingMember, e);
                    }
                }
                else
                {
                    if (char.IsUpper(element.Name[0]))
                    {
                        PropertyInfo propertyInfo;

                        if (element.Name.IndexOf('.') != -1)
                        {
                            propertyInfo = controlType.GetProperty(element.Name.Split('.')[1]);
                        }
                        else
                        {
                            propertyInfo = controlType.GetProperty(element.Name);
                        }

                        if (propertyInfo == null)
                        {
                            Log.Info("GUIControlFactory.UpdateControlWithXmlData: '{0}' does not contain a definition for '{1}'",
                                     controlType, element.Name);
                            return;
                        }

                        string xml = element.OuterXml;

                        if (xml.IndexOf("Button.") != -1)
                        {
                            xml = xml.Replace("Button.", "GUIControl.");
                        }
                        else if (xml.IndexOf("Window.") != -1)
                        {
                            xml = xml.Replace("Window.", "GUIWindow.");
                        }

                        XamlParser.LoadXml(xml, XmlNodeType.Element, control, filename);
                    }
                }
            }

            //Set parent control's visible condition as ours wn if we're children of a group
            if (!hasVisiblecondition)
            {
                XmlNode parentNode = pControlNode.ParentNode;
                if (IsGroupControl(parentNode))
                {
                    XmlDocument tempDoc                = new XmlDocument();
                    XmlNode     elem                   = tempDoc.CreateElement("visible");
                    int         iVisibleCondition      = 0;
                    bool        allowHiddenFocus       = true;
                    string      parentVisiblecondition = GetVisibleConditionXML(parentNode);
                    if (!string.IsNullOrEmpty(parentVisiblecondition) && parentVisiblecondition != "yes" &&
                        parentVisiblecondition != "no")
                    {
                        elem.InnerText = parentVisiblecondition;
                        XmlNode visibleNode = pControlNode.OwnerDocument.ImportNode(elem, true);
                        pControlNode.AppendChild(visibleNode);
                        GetConditionalVisibility(visibleNode, control, ref iVisibleCondition, ref allowHiddenFocus);
                        control.SetVisibleCondition(iVisibleCondition, allowHiddenFocus);
                    }
                }
            }
            if (animations.Count > 0)
            {
                control.SetAnimations(animations);
            }
            if (thumbAnimations.Count > 0)
            {
                control.SetThumbAnimations(thumbAnimations);
            }
        }