public DataHelper(
            Type targetType,
            EditorLSDatabase sourceEditor,
            LSDatabase sourceDatabase,
            string displayName,
            string dataCodeName,
            string dataFieldName,
            SortInfo[] sorts)
        {
            Sorts            = sorts;
            this.TargetType  = targetType;
            SourceEditor     = sourceEditor;
            this.DisplayName = displayName;
            SourceDatabase   = sourceDatabase;
            DataCodeName     = dataCodeName;
            _dataFieldName   = dataFieldName;

            FieldInfo info = sourceDatabase.GetType().GetField(_dataFieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            _getData = () => (DataItem[])info.GetValue(sourceDatabase);
            _setData = (value) => info.SetValue(sourceDatabase, value);
            if (Data == null)
            {
                Data = (DataItem[])Array.CreateInstance(TargetType, 0);
            }
            DataItemAttribute dataAttribute = (DataItemAttribute)Attribute.GetCustomAttribute(targetType, typeof(DataItemAttribute));

            _dataAttribute = dataAttribute ?? new DataItemAttribute();
        }
        public DataHelper(
            Type targetType,
            EditorLSDatabase sourceEditor,
            LSDatabase sourceDatabase,
            string displayName,
            string dataFieldName,
            SortInfo[] sorts,
            out bool valid)
        {
            Sorts = sorts;
            this.TargetType = targetType;
            SourceEditor = sourceEditor;
            this.DisplayName = displayName;
            SourceDatabase = sourceDatabase;
            _dataFieldName = dataFieldName;

            FieldInfo info = sourceDatabase.GetType().GetField(_dataFieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (info == null) {
                Debug.Log (string.Format ("Field with fieldName of {0} not found.", dataFieldName));
                valid = false;
                return;
            }

            _getData = () => (DataItem[])info.GetValue(sourceDatabase);
            _setData = (value) => info.SetValue(sourceDatabase, value);
            if (Data == null)
                Data = (DataItem[])Array.CreateInstance (TargetType,0);
            DataItemAttribute dataAttribute = (DataItemAttribute)Attribute.GetCustomAttribute(targetType, typeof (DataItemAttribute));
            _dataAttribute = dataAttribute ?? new DataItemAttribute ();
            valid = true;
        }
        public DataHelper(
            Type targetType,
            EditorLSDatabase sourceEditor,
            LSDatabase sourceDatabase,
            string displayName,
            string dataCodeName,
            string dataFieldName,
            SortInfo[] sorts)
        {
            Sorts = sorts;
            this.TargetType = targetType;
            SourceEditor = sourceEditor;
            this.DisplayName = displayName;
            SourceDatabase = sourceDatabase;
            DataCodeName = dataCodeName;
            _dataFieldName = dataFieldName;

            FieldInfo info = sourceDatabase.GetType().GetField(_dataFieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            _getData = () => (DataItem[])info.GetValue(sourceDatabase);
            _setData = (value) => info.SetValue(sourceDatabase, value);
            if (Data == null)
                Data = (DataItem[])Array.CreateInstance (TargetType,0);
            DataItemAttribute dataAttribute = (DataItemAttribute)Attribute.GetCustomAttribute(targetType, typeof (DataItemAttribute));
            _dataAttribute = dataAttribute ?? new DataItemAttribute ();
        }
        public override sealed void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (initialized == false) {
                Initialize ();
            }

            dataItemAttribute =
            dataItemAttribute
                ?? (DataItemAttribute)Attribute.GetCustomAttribute (LSEditorUtility.GetPropertyType (property), typeof(DataItemAttribute), false)
                ?? new DataItemAttribute ();
            ;

            Rect pos = position;
            pos.height = defaultPropertyHeight;
            serializedProperties.Clear ();

            float height = defaultPropertyHeight;

            string saveID = property.propertyPath;

            SerializedProperty nameProp = property.FindPropertyRelative ("_name");
            SerializedProperty iterationProperty = nameProp.Copy ();

            if (EditorLSDatabase.foldAll) {
                LSEditorUtility.SetPersistentFlag (saveID, false);
            }

            if (LSEditorUtility.PersistentFoldout (pos,
                                               nameProp.stringValue,
                                               saveID
            )) {
                pos.y += defaultPropertyHeight;
                if (dataItemAttribute.WritableName) {
                    serializedProperties.Add (nameProp);
                }

                int beginningDepth = iterationProperty.depth;
                while (iterationProperty.NextVisible(true)) {
                    if (iterationProperty.depth != beginningDepth) {
                        break;
                    }
                    serializedProperties.Add (iterationProperty.Copy ());
                }
                pos.x += defaultPropertyHeight;
                pos.width -= defaultPropertyHeight;
                for (int i = 0; i < serializedProperties.Count; i++) {
                    SerializedProperty curProp = serializedProperties[i];
                    float propertyHeight = EditorGUI.GetPropertyHeight (curProp,new GUIContent(),true);
                    EditorGUI.PropertyField (pos, curProp, true);
                    pos.y += propertyHeight;
                    height += propertyHeight;
                }
            }

            LSEditorUtility.SetPersistentValue (saveID, height);
        }
        public DataHelper(
            Type targetType,
            EditorLSDatabase sourceEditor,
            LSDatabase sourceDatabase,
            string displayName,
            string dataFieldName,
            SortInfo[] sorts,
            out bool valid)
        {
            Sorts            = sorts;
            this.TargetType  = targetType;
            SourceEditor     = sourceEditor;
            this.DisplayName = displayName;
            SourceDatabase   = sourceDatabase;
            _dataFieldName   = dataFieldName;

            FieldInfo info = sourceDatabase.GetType().GetField(_dataFieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (info == null)
            {
                Debug.Log(string.Format("Field with fieldName of {0} not found.", dataFieldName));
                valid = false;
                return;
            }

            _getData = () => (DataItem[])info.GetValue(sourceDatabase);
            _setData = (value) => info.SetValue(sourceDatabase, value);
            if (Data == null)
            {
                Data = (DataItem[])Array.CreateInstance(TargetType, 0);
            }
            DataItemAttribute dataAttribute = (DataItemAttribute)Attribute.GetCustomAttribute(targetType, typeof(DataItemAttribute));

            _dataAttribute = dataAttribute ?? new DataItemAttribute();
            valid          = true;
        }
        public sealed override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (initialized == false)
            {
                Initialize();
            }

            dataItemAttribute =
                dataItemAttribute
                ?? (DataItemAttribute)Attribute.GetCustomAttribute(LSEditorUtility.GetPropertyType(property), typeof(DataItemAttribute), false)
                ?? new DataItemAttribute();
            ;

            Rect pos = position;

            pos.height = defaultPropertyHeight;
            serializedProperties.Clear();


            float height = defaultPropertyHeight;

            string saveID = property.propertyPath;

            SerializedProperty nameProp          = property.FindPropertyRelative("_name");
            SerializedProperty iterationProperty = nameProp.Copy();


            if (EditorLSDatabase.foldAll)
            {
                LSEditorUtility.SetPersistentFlag(saveID, false);
            }

            if (LSEditorUtility.PersistentFoldout(pos,
                                                  nameProp.stringValue,
                                                  saveID
                                                  ))
            {
                pos.y += defaultPropertyHeight;
                if (dataItemAttribute.WritableName)
                {
                    serializedProperties.Add(nameProp);
                }


                int beginningDepth = iterationProperty.depth;
                while (iterationProperty.NextVisible(true))
                {
                    if (iterationProperty.depth <= beginningDepth - 1)
                    {
                        //serializedProperties.RemoveAt(serializedProperties.Count - 1);
                        break;
                    }
                    if (iterationProperty.depth > beginningDepth)
                    {
                        continue;
                    }
                    serializedProperties.Add(iterationProperty.Copy());
                }
                pos.x     += defaultPropertyHeight;
                pos.width -= defaultPropertyHeight;
                for (int i = 0; i < serializedProperties.Count; i++)
                {
                    SerializedProperty curProp = serializedProperties[i];
                    float propertyHeight       = EditorGUI.GetPropertyHeight(curProp, new GUIContent(), true);
                    EditorGUI.PropertyField(pos, curProp, true);
                    pos.y  += propertyHeight;
                    height += propertyHeight;
                }
            }

            LSEditorUtility.SetPersistentValue(saveID, height);
        }