public static List<object> ExtractElement(object root, string propertyName, bool includeMethod, Type[] exceptTypes, Type[] exceptAttributeType, string[] attributeNames)
        {
            Dictionary<string, object> objectReferences = new Dictionary<string, object>();
            List<object> result = new List<object>();

            object obj;
            if (string.IsNullOrEmpty(propertyName))
                obj = root;
            else
            {
                obj = GetPropertyValue(root, propertyName);
            }

            if (obj == null) return result;

            PropertyInfo[] propList = obj.GetType().GetProperties();

            foreach (var prop in propList)
            {
                if (exceptTypes != null)
                {
                    if (IsHaveType(exceptTypes, prop.PropertyType) == true) continue;
                }

                Attribute[] attr = Attribute.GetCustomAttributes(prop);

                if (exceptAttributeType != null)
                {
                    bool existExceptAttribute = Array.Exists(exceptAttributeType,
                        targetType => Array.Exists(attr, attribute => attribute.GetType() == targetType));
                    if (existExceptAttribute == true) continue;
                }

                FAAttribute faAttr = GetFAPropertyAttribute(attr);
                if (faAttr != null)
                {
                    if (attributeNames != null && Array.IndexOf(attributeNames, faAttr.GroupName) < 0) continue;

                    var value = prop.GetValue(obj, null);

                    dynamic attributeGroup = null;

                    if (string.IsNullOrEmpty(faAttr.GroupName) == false)
                    {
                        if (objectReferences.ContainsKey(faAttr.GroupName) == false)
                        {
                            attributeGroup = new PropertyContainer();
                            attributeGroup.Value = new List<object>();
                            attributeGroup.Name = faAttr.GroupName;
                            objectReferences.Add(faAttr.GroupName, attributeGroup);
                            result.Add(attributeGroup);
                        }
                        else
                        {
                            attributeGroup = objectReferences[faAttr.GroupName] as PropertyContainer;
                        }
                    }

                    if (prop.PropertyType == typeof(bool))
                    {
                        BooleanPropertyValue propertyValue = new BooleanPropertyValue();
                        propertyValue.Name = prop.Name;
                        propertyValue.SetObject(root, ConcatPropertyNames(propertyName, prop.Name), obj, prop.Name);

                        if (attributeGroup == null)
                            result.Add(propertyValue);
                        else
                            attributeGroup.Value.Add(propertyValue);
                    }
                    else if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string))
                    {
                        if (prop.GetSetMethod(false) == null)
                        {
                            ReadOnlyPropertyValue propertyValue = new ReadOnlyPropertyValue();
                            propertyValue.Name = prop.Name;
                            propertyValue.SetObject(root, ConcatPropertyNames(propertyName, prop.Name));

                            if (attributeGroup == null)
                                result.Add(propertyValue);
                            else
                                attributeGroup.Value.Add(propertyValue);
                        }
                        else
                        {
                            PropertyValue propertyValue = new PropertyValue();
                            propertyValue.Name = prop.Name;
                            propertyValue.SetObject(root, ConcatPropertyNames(propertyName, prop.Name), obj, prop.Name);

                            if (attributeGroup == null)
                                result.Add(propertyValue);
                            else
                                attributeGroup.Value.Add(propertyValue);
                        }
                    }
                    else if (value is System.Collections.IList)
                    {
                        ListPropertyValue propertyValue = new ListPropertyValue();
                        propertyValue.Name = prop.Name;
                        propertyValue.Value = value;

                        if (attributeGroup == null)
                            result.Add(propertyValue);
                        else
                            attributeGroup.Value.Add(propertyValue);
                    }
                    else if (value is System.Collections.IDictionary)
                    {
                        PropertyContainer propertyValue = new PropertyContainer();
                        propertyValue.Name = prop.Name;

                        List<object> propertyValuesList = new List<object>();
                        foreach (System.Collections.DictionaryEntry item in ((System.Collections.IDictionary)value))
                        {
                            PropertyContainer subPropertyValue = new PropertyContainer();
                            subPropertyValue.Name = item.Key.ToString();
                            subPropertyValue.Value = ExtractElement(item.Value, string.Empty, includeMethod, exceptTypes, exceptAttributeType, attributeNames);
                            propertyValuesList.Add(subPropertyValue);
                        }

                        propertyValue.Value = propertyValuesList;
                        if (attributeGroup == null)
                            result.Add(propertyValue);
                        else
                            attributeGroup.Value.Add(propertyValue);
                    }
                    else if (prop.PropertyType.IsEnum)
                    {
                        EnumPropertyValue propertyValue = new EnumPropertyValue();
                        propertyValue.Name = prop.Name;
                        propertyValue.Value = value;
                        propertyValue.SetObject(root, ConcatPropertyNames(propertyName, prop.Name), obj, prop.Name);

                        if (attributeGroup == null)
                            result.Add(propertyValue);
                        else
                            attributeGroup.Value.Add(propertyValue);
                    }
                    else
                    {
                        var list = ExtractElement(root, ConcatPropertyNames(propertyName, prop.Name), includeMethod, null, exceptAttributeType, attributeNames);

                        if (list.Count > 0)
                        {
                            PropertyContainer propertyValue = new PropertyContainer();
                            propertyValue.Name = prop.Name;
                            propertyValue.Value = list;

                            if (attributeGroup == null)
                                result.Add(propertyValue);
                            else
                                attributeGroup.Value.Add(propertyValue);
                        }
                        else
                        {
                            ReadOnlyPropertyValue propertyValue = new ReadOnlyPropertyValue();
                            propertyValue.Name = prop.Name;
                            propertyValue.SetObject(root, ConcatPropertyNames(propertyName, prop.Name));

                            if (attributeGroup == null)
                                result.Add(propertyValue);
                            else
                                attributeGroup.Value.Add(propertyValue);
                        }
                    }
                }
            }

            if (includeMethod)
                AddMethodInfo(obj, result);

            return result;
        }
 private void CreateDebugList()
 {
     foreach (var item in EquipmentManagerInstance.EquipmentList)
     {
         PropertyContainer pc = new PropertyContainer();
         pc.Value = ObjectElementExtractor.ExtractElement(item.Value, string.Empty, true, null, null, null);
         pc.Name = item.Key;
         DebugList.Add(pc);
     }
 }