private MemoryBrowser Create(DevUIView resultView, object viewObject, bool autoupdate = false, Action <object, object> onValueChanged = null)
        {
            DevUIButton compButton = new DevUIButton(viewObject.GetType().ToString(), () => { });

            resultView.AddElement(compButton);

            MemoryBrowser mB = new MemoryBrowser(viewObject);

            Dictionary <string, DevUIKeyValue> dict = new Dictionary <string, DevUIKeyValue>();

            foreach (string key in mB.rxCurrentSnapShot.Keys)
            {
                object obj = mB.rxCurrentSnapShot[key];

                if (obj == null || MemoryBrowser.IsSimple(obj.GetType()) || obj is Vector3 || obj is Vector2 || obj is Vector4)
                {
                    DevUIKeyValue uiKV = new DevUIKeyValue(key, obj == null ? "null" : obj.ToString());
                    uiKV.OnValueChangeRequested = (newVal) => {
                        mB.SetValue(key, newVal);
                        if (onValueChanged != null)
                        {
                            onValueChanged(key, newVal);
                        }
                    };
                    resultView.AddElement(uiKV);
                    dict[key] = uiKV;
                }
                else if (obj is IDevUIVisible)
                {
                    DevUIKeyValue uiKV = new DevUIKeyValue(key, obj == null ? "null" : "'" + obj.ToString() + "'");
                    resultView.AddElement(uiKV);
                    // TODO: Detect changes in custom-type
                }
                else if (obj is IList && ((IList)obj).Count > 0)
                {
                    IList  thelist      = (IList)obj;
                    object firstElement = thelist[0];
                    if (firstElement is IDevUIVisible)
                    {
                        resultView.AddElement(new DevUIButton(key + "(List)", null));

                        for (int i = 0; i < thelist.Count; i++)
                        {
                            object        listObj = thelist[i];
                            DevUIKeyValue uiKV    = new DevUIKeyValue(key, i + "| " + listObj == null ? "null" : "'" + listObj.ToString() + "'");
                            resultView.AddElement(uiKV);
                            // TODO: detect list changes
                        }
                    }
                }
            }

            if (autoupdate && dict.Count > 0)
            {
                mB.rxCurrentSnapShot
                .ObserveReplace()
                .Subscribe(evt => {
                    if (evt.OldValue == evt.NewValue)
                    {
                        return;
                    }

                    string key = evt.Key;
                    if (dict.ContainsKey(key))
                    {
                        DevUIKeyValue uiKV = dict[key];
                        uiKV.Value         = evt.NewValue.ToString();
                    }
                })
                .AddTo(resultView.disposables);     // when the view is disposed, also dispose this subscription
            }
            else
            {
                // TODO: no button if we cannot show any values?
                resultView.RemoveElement(compButton);
            }


            // Poll the data at a this interval for every component
            // TODO: Make this more efficient: only the view that is in focus!?
            timeService.CreateGlobalTimer(1.0f, () => {
                mB.UpdateCurrentSnapshot();
                logging.Info("UPDATED SNAPSHOT");
            }, 0);

            return(mB);
        }
        public override IObservable <float> LoadViews()
        {
            List <string> viewFiles = fileSystem.GetFilesInDomain(FileSystem.FSDomain.DevUIViews, "", "*.json");

            float progressFactor       = 1.0f / viewFiles.Count;
            float progress             = 0;
            IObservable <float> result = Observable.Return(progressFactor);

            // check if we already used a viewname
            HashSet <string> usedViewNames = new HashSet <string>();

            List <string> tempCurrentViewFiles = new List <string>(viewPathsLoaded);

            foreach (string viewFile in viewFiles)
            {
                result = result.Concat(Observable.Start(() => {
                    Debug.Log("thread: " + System.Threading.Thread.CurrentThread.Name);
                    // did we already load this view? if yes, skip
                    if (tempCurrentViewFiles.Contains(viewFile))
                    {
                        // remove file from temp list (the ones that stays in list are the ones to be deleted afterwards)
                        tempCurrentViewFiles.Remove(viewFile);
                        return(null);
                    }

                    string viewDataAsString = fileSystem.LoadFileAsString(viewFile);
                    return(viewDataAsString);
                }).ObserveOnMainThread().Select(fileData => {
                    try {
                        if (fileData != null)
                        {
                            DevUIView viewData = serializer.DeserializeToObject <DevUIView>(fileData);

                            if (usedViewNames.Contains(viewData.Name))
                            {
                                logging.Warn("There is already already a view with the name " + viewData.Name + "! This results in merged views");
                            }

                            DevUIView view = GetView(viewData.Name);
                            if (view == null)
                            {
                                // a new view
                                view = CreateView(viewData.Name, viewData.createdDynamically);
                                view.extensionAllowed = viewData.extensionAllowed;
                            }
                            usedViewNames.Add(viewData.Name);
                            view.currentFilename = viewFile;

                            foreach (DevUIElement uiElem in viewData.uiElements)
                            {
                                view.AddElement(uiElem, false);
                            }

                            viewPathsLoaded.Add(viewFile);
                        }
                    }
                    catch (Exception e) {
                        Debug.LogWarning("Could not load viewElement! Ignoring!");
                    }
                    return("");
                }).Select(_ => { progress += progressFactor; return(progress); }));
            }

            result = result.Finally(() => {
                // are there any files left, that were loaded before, but now vanished?
                foreach (string oldPath in tempCurrentViewFiles)
                {
                    DevUIView view = rxViews.Where(v => v.currentFilename == oldPath).FirstOrDefault();
                    if (view != null)
                    {
                        RemoveViewFromModel(view);
                    }
                }
            });

            return(result.ObserveOnMainThread());
        }