/// <summary>
            /// Gets all properties and fields from a given C# Type object and/or Unity
            /// Type property field.  Returns true if we found any.
            /// </summary>
            /// <returns>
            /// All properties and fields exposed (does not overwrite existing list).
            /// </returns>
            /// <param name='obj'>
            /// The optional C# Type object.
            /// </param>
            /// <param name='unityPropertyField'>
            /// The optional Unity Type property field.
            /// </param>
            /// <param name='allPropertiesAndFields'>
            /// If set to <c>true</c>, all the properties and fields.
            /// </param>
            public static List <OCPropertyField> GetAllPropertiesAndFields
                (object obj = null
                , SerializedProperty unityPropertyField = null
                , OCExposure exposure = OCExposure.None
                )
            {
                List <OCPropertyField> allPropertyFields = new List <OCPropertyField>();
                Type type = obj.GetType();

                if
                (
                    type == null &&
                    unityPropertyField == null
                )
                {
                    return(null);
                }

                Stack <OCPropertyField> candidates = new Stack <OCPropertyField>();

                if (unityPropertyField != null)
                {
                    while (unityPropertyField.NextVisible(true))
                    {
                        if (unityPropertyField.editable && !unityPropertyField.DuplicateCommand())
                        {
                            string publicName =
                                ObjectNames.NicifyVariableName(unityPropertyField.name);

                            if (ExcludedPropertyFieldPublicNames.Contains(publicName))
                            {
                                continue;
                            }

                            candidates.Push
                            (
                                new OCPropertyField(obj, unityPropertyField.Copy())
                            );
                        }
                    }

                    unityPropertyField.Reset();
                }

                if (type != null)
                {
//			Debug.Log("We found a type!");
                    MemberInfo[] memberInfos = type.GetMembers(OCBindingFlags);

                    foreach (MemberInfo info in memberInfos)
                    {
                        if (
                            (info.MemberType == MemberTypes.Field &&
                             !(info as FieldInfo).IsSpecialName
                            )
                            ||
                            (info.MemberType == MemberTypes.Property &&
                             !(info as PropertyInfo).IsSpecialName &&
                             (info as PropertyInfo).CanRead &&
                             (info as PropertyInfo).CanWrite
                            )
                            )
                        {
//					Debug.Log("We found a good member info! :" + info.Name);

                            string publicName = ObjectNames.NicifyVariableName(info.Name);

                            if (ExcludedPropertyFieldPublicNames.Contains(publicName))
                            {
                                continue;
                            }
//					Debug.Log("We found a good candidate! :" + info.Name);
                            candidates.Push(new OCPropertyField(obj, info));
                        }
                    }
                }

                while (candidates.Count > 0)
                {
                    OCPropertyField candidate = candidates.Pop();

                    OCPropertyField match =
                        allPropertyFields.Find(p => p.PublicName == candidate.PublicName);

                    if (match != null && match != default(OCPropertyField) && (match.UnityPropertyField != null || match.Instance != null))
                    {
                        match = candidate;
                    }
                    else
                    {
                        allPropertyFields.Insert(0, candidate);
                    }
                }

                if (allPropertyFields.Count > 0)
                {
                    return(allPropertyFields);
                }
                else
                {
                    return(null);
                }
            }
	/////////////////////////////////////////////////////////////////////////////

  #endregion

	/////////////////////////////////////////////////////////////////////////////

  #region Public Member Functions

	/////////////////////////////////////////////////////////////////////////////

	public OCExposePropertyFieldsAttribute 
		(OCExposure exposure = OCExposure.PropertiesAndFields)
	{
		_exposure = exposure;
	}
            /////////////////////////////////////////////////////////////////////////////

            #endregion

            /////////////////////////////////////////////////////////////////////////////

            #region Public Member Functions

            /////////////////////////////////////////////////////////////////////////////

            public OCExposePropertyFieldsAttribute
                (OCExposure exposure = OCExposure.PropertiesAndFields)
            {
                _exposure = exposure;
            }