public static ComponentMethodRef <T> ComponentMethodRefField <T>(ComponentMethodRef <T> componentMethodRef, Type returnType, GUIContent label, ref bool dataChanged)
                {
                    if (label == null)
                    {
                        label = new GUIContent();
                    }

                    label.text += " (" + componentMethodRef + ")";

                    bool editorCollapsed = !EditorGUILayout.Foldout(!componentMethodRef._editorCollapsed, label);

                    if (editorCollapsed != componentMethodRef._editorCollapsed)
                    {
                        componentMethodRef._editorCollapsed = editorCollapsed;
                        dataChanged = true;
                    }

                    if (!editorCollapsed)
                    {
                        int origIndent = EditorGUI.indentLevel;
                        EditorGUI.indentLevel++;

                        bool componentChanged = false;
                        ComponentRef <Component> component = SerializationEditorGUILayout.ObjectField(componentMethodRef.GetComponentRef(), new GUIContent("Object"), ref componentChanged);

                        Component currentComponent = component.GetBaseComponent();

                        if (currentComponent != null)
                        {
                            string[] methodNames = GetMethods(currentComponent, returnType);

                            if (methodNames.Length > 0)
                            {
                                int currentIndex = 0;

                                for (int i = 0; i < methodNames.Length; i++)
                                {
                                    if (methodNames[i] == componentMethodRef.GetMethodName())
                                    {
                                        currentIndex = i;
                                        break;
                                    }
                                }

                                EditorGUI.BeginChangeCheck();

                                int newIndex = EditorGUILayout.Popup("Method", currentIndex, methodNames);

                                if (EditorGUI.EndChangeCheck() || componentChanged)
                                {
                                    componentMethodRef = new ComponentMethodRef <T>(component, methodNames[newIndex]);
                                    dataChanged        = true;
                                }
                            }
                            else if (componentChanged)
                            {
                                componentMethodRef = new ComponentMethodRef <T>(component, string.Empty);
                                dataChanged        = true;
                            }
                        }
                        else if (componentChanged)
                        {
                            componentMethodRef = new ComponentMethodRef <T>(component, string.Empty);
                            dataChanged        = true;
                        }

                        EditorGUI.indentLevel = origIndent;
                    }

                    return(componentMethodRef);
                }
                private static bool RenderObjectField <T>(ref ComponentRef <T> componentRef) where T : class
                {
                    bool       dataChanged = false;
                    GameObject gameObject  = null;

                    Component currentComponent = componentRef.GetBaseComponent();

                    //If T is a type of component can just use a normal object field
                    if (typeof(Component).IsAssignableFrom(typeof(T)))
                    {
                        Component component = EditorGUILayout.ObjectField(kLabel, currentComponent, typeof(T), true) as Component;
                        gameObject = component != null ? component.gameObject : null;
                    }
                    //Otherwise allow gameobject to be set and deal with typing when rendering index
                    else
                    {
                        gameObject = (GameObject)EditorGUILayout.ObjectField(kLabel, currentComponent != null ? currentComponent.gameObject : null, typeof(GameObject), true);
                    }

                    //Render drop down for typed components on the gameobject
                    if (gameObject != null)
                    {
                        //Show drop down to allow selecting different components on same game object
                        int         currentIndex  = 0;
                        Component[] allComponents = gameObject.GetComponents <Component>();

                        List <GUIContent> validComponentLabels = new List <GUIContent>();
                        List <Component>  validComponents      = new List <Component>();
                        List <Type>       validComponentTypes  = new List <Type>();

                        for (int i = 0; i < allComponents.Length; i++)
                        {
                            T typedComponent = allComponents[i] as T;

                            if (typedComponent != null)
                            {
                                int numberComponentsTheSameType = 0;
                                foreach (Type type in validComponentTypes)
                                {
                                    if (type == allComponents[i].GetType())
                                    {
                                        numberComponentsTheSameType++;
                                    }
                                }

                                validComponentLabels.Add(new GUIContent(allComponents[i].GetType().Name + (numberComponentsTheSameType > 0 ? " (" + numberComponentsTheSameType + ")" : "")));
                                validComponents.Add(allComponents[i]);
                                validComponentTypes.Add(allComponents[i].GetType());

                                if (allComponents[i] == currentComponent)
                                {
                                    currentIndex = validComponents.Count - 1;
                                }
                            }
                        }

                        if (validComponents.Count > 1)
                        {
                            int selectedIndex = EditorGUILayout.Popup(kLabel, currentIndex, validComponentLabels.ToArray());
                            dataChanged = currentComponent != validComponents[selectedIndex] || componentRef.GetComponentIndex() != selectedIndex;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType(), validComponents[selectedIndex], selectedIndex);
                            }
                        }
                        else if (validComponents.Count == 1)
                        {
                            dataChanged = currentComponent != validComponents[0] || componentRef.GetComponentIndex() != 0;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType(), validComponents[0], 0);
                            }
                        }
                        else if (validComponents.Count == 0)
                        {
                            dataChanged = currentComponent != null || componentRef.GetComponentIndex() != 0;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType());
                            }
                        }
                    }
                    else
                    {
                        dataChanged = currentComponent != null || componentRef.GetComponentIndex() != 0;
                        if (dataChanged)
                        {
                            componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType());
                        }
                    }

                    return(dataChanged);
                }