private void Awake()
    {
        if (IED == null)
        {
            IED = new MixedRealityPointerEventData(EventSystem.current);
        }

        if (FED == null)
        {
            FED = new FocusEventData(EventSystem.current);
        }

        ShareStateTypes.RegisterCustomTypes();
    }
    void ShowAddWatch()
    {
        GameObject thisObject = ((Component)target).gameObject;

        if (sourceObject == null)
        {
            sourceObject = thisObject;
        }

        Rect rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);

        // Display the info we've already picked
        float width = 60;

        EditorGUI.LabelField(new Rect(rect.x, rect.y, width, rect.height), "Add field:", EditorStyles.toolbarButton);
        rect.x     += width;
        rect.width -= width;
        if (com != null && DrawDeleteable(com.GetType().Name, ref rect))
        {
            com    = null;
            member = null;
        }
        if (member != null && DrawDeleteable(member.Name, ref rect))
        {
            member = null;
        }

        // And now, draw the selection part
        if (com == null)
        {
            // GameObject component picker
            List <Component> coms = new List <Component>(sourceObject.GetComponents <Component>());
            int com = EditorGUI.Popup(rect, -1, coms.ConvertAll(a => new GUIContent(a.GetType().Name)).ToArray(), EditorStyles.toolbarPopup);
            EditorGUI.DrawRect(rect, new Color(1, 1, 1, 0.4f));
            if (com != -1)
            {
                this.com = coms[com];
            }
        }
        else if (member == null)
        {
            // Get all fields and properties from the current component
            List <MemberInfo> fields = new List <MemberInfo>();
            fields.AddRange(com.GetType().GetProperties(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic));
            fields.AddRange(com.GetType().GetFields(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic));
            fields.Sort((a, b) => a.Name.CompareTo(b.Name));

            // filter fields that aren't shareable
            for (int i = 0; i < fields.Count; i++)
            {
                PropertyInfo prop = fields[i] as PropertyInfo;
                FieldInfo    f    = fields[i] as FieldInfo;
                if ((prop != null && (!ShareStateTypes.CanSerialize(prop.PropertyType) || (!prop.CanRead || !prop.CanWrite))) ||
                    (f != null && (!ShareStateTypes.CanSerialize(f.FieldType))))
                {
                    fields.RemoveAt(i);
                    i--;
                }
            }

            // pick a field
            int field = EditorGUI.Popup(rect, -1, fields.ConvertAll(a => new GUIContent(a.Name)).ToArray(), EditorStyles.toolbarPopup);
            EditorGUI.DrawRect(rect, new Color(1, 1, 1, 0.4f));
            if (field != -1)
            {
                member    = fields[field];
                frequency = 0.5f;
            }
        }
        else
        {
            // display the update interval item
            frequency = EditorGUI.FloatField(new Rect(rect.x, rect.y, rect.width - 32, rect.height + 2), frequency);
            // And here we do adding an item to the list
            if (GUI.Button(new Rect(rect.xMax - 32, rect.y, 32, rect.height), "+", EditorStyles.toolbarButton))
            {
                watches.InsertArrayElementAtIndex(watches.arraySize);
                SerializedProperty watch = watches.GetArrayElementAtIndex(watches.arraySize - 1);
                watch.FindPropertyRelative("component").objectReferenceValue = com;
                watch.FindPropertyRelative("member").stringValue             = member.Name;
                watch.FindPropertyRelative("frequency").floatValue           = frequency;

                com    = null;
                member = null;
            }
        }

        GameObject newObject = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Add Field Source", "Where does this pick Components from? Must be a child object of this GameObject."), sourceObject, typeof(GameObject), true);

        // make sure the source object is a child of this object, or is this object
        if (newObject != sourceObject)
        {
            Transform curr  = newObject == null ? null : newObject.transform;
            bool      valid = false;
            while (curr != null)
            {
                if (curr == thisObject.transform)
                {
                    valid = true;
                    break;
                }
                curr = curr.parent;
            }
            if (!valid)
            {
                newObject = null;
            }

            sourceObject = newObject;
            com          = null;
            member       = null;
        }
    }