private void populateNextLevel(System.Object subTreeRoot)
        {
            //build a new wrapper for this next level
            var wrapper = new GameObject("sub_tree_wrapper");

            //wrapper.transform.position = this.transform.position;
            wrapper.transform.SetParent(this.transform.parent, false);
            wrapper.AddComponent <HorizontalLayoutGroup>();
            wrapper.GetComponent <HorizontalLayoutGroup>().spacing = 5;


            if (InspectorVisualization.IsList(subTreeRoot))
            {
                Debug.Log("inputobject is a list");
                foreach (var item in (IEnumerable)subTreeRoot)
                {
                    var inspectabelgo = InspectorVisualization.generateInspectableElementGameObject(item, wrapper);
                }
            }

            else if (InspectorVisualization.IsDictionary(subTreeRoot))
            {
                Debug.Log("inputobject is a dictionary");
                foreach (var pair in (IEnumerable)subTreeRoot)
                {
                    var realpair = DictionaryHelpers.CastFrom(pair);
                    var key      = realpair.Key;
                    var value    = realpair.Value;

                    InspectorVisualization.generateInspectableElementGameObject(value, wrapper);
                }
            }



            else
            {
                Debug.Log("inputobject is a object");

                if (subTreeRoot is IDynamicMetaObjectProvider)
                {
                    Debug.Log("inputobject is a dynamic object");
                    var names  = new List <string>();
                    var dynobj = subTreeRoot as IronPython.Runtime.Binding.IPythonExpandable;
                    if (dynobj != null)
                    {
                        names.AddRange(dynobj.Context.LanguageContext.GetMemberNames(Expression.Constant(dynobj)));
                    }

                    //filter names so that python private and builtin members do not show
                    var filterednames = names.Where(x => x.StartsWith("__") != true).ToList();

                    foreach (var name in filterednames)
                    {
                        var value = InspectorVisualization.GetDynamicValue(dynobj, name);

                        if (value != null)
                        {
                            InspectorVisualization.generateInspectableElementGameObject(value, wrapper);
                        }
                    }
                }

                // if object was not dynamic use regular reflection
                else
                {
                    Debug.Log("inputobject is a non dynamic object");
                    var propertyInfos = subTreeRoot.GetType().GetProperties(
                        BindingFlags.Public | BindingFlags.NonPublic              // Get public and non-public
                        | BindingFlags.Static | BindingFlags.Instance             // Get instance + static
                        | BindingFlags.FlattenHierarchy);                         // Search up the hierarchy



                    foreach (var prop in propertyInfos.ToList())
                    {
                        if (prop.GetIndexParameters().Length > 0)
                        {
                            // Property is an indexer
                            Debug.Log("this property is an indexed property, for now we won't reflect further");
                            continue;
                        }
                        try
                        {
                            var value = prop.GetValue(subTreeRoot, null);
                            InspectorVisualization.generateInspectableElementGameObject(value, wrapper, prop.Name);
                        }
                        catch (Exception e)
                        {
                            Debug.Log("could not get property" + prop.Name);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// where main work is done of generating a new inspectable object and setting its properties, the object is then made a child of the parent
        ///
        /// </summary>
        ///
        /// <param name="someObject"></param>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static GameObject generateInspectableElementGameObject(object someObject, GameObject parent, string name = null)
        {
            if (someObject == null)
            {
                //GameObject.Destroy(parent);
                return(null);
            }

            var wrapper = new GameObject("subelement_wrapper");

            //wrapper.transform.position = parent.transform.position;
            wrapper.transform.SetParent(parent.transform, false);
            wrapper.AddComponent <VerticalLayoutGroup>();
            //wrapper.GetComponent<RectTransform>().sizeDelta = new Vector2(1,1);
            //wrapper.transform.Rotate(0,90,0);

            //TODO replace with call to specific item type depending on item system.type
            var element = Resources.Load <GameObject>("listele");

            var instantiatedelement = GameObject.Instantiate(element) as GameObject;

            instantiatedelement.name = (someObject.GetType().ToString());
            //instantiatedelement.transform.position = wrapper.transform.position;

            instantiatedelement.transform.SetParent(wrapper.transform, false);

            var inspectable = instantiatedelement.AddComponent <InspectableElement>();

            inspectable.ElementType = someObject.GetType();
            inspectable.Reference   = someObject;
            inspectable.Name        = name;
            Debug.Log("building inspectable element representing: " + someObject.ToString());



            //TODO extract constants, fix this mess, possibly recalc based on distance to camera
            if (parent.transform.parent.GetChild(0).GetComponentInChildren <Text>().fontSize == 14)
            {
                //we are still creating the root visualization, so just set the size to 500
                parent.transform.parent.GetChild(0).GetComponentInChildren <Text>().fontSize = 500;
            }
            else
            {
                //in all other cases halve it
                var parentfontsize = parent.transform.parent.GetChild(0).GetComponentInChildren <Text>().fontSize;
                inspectable.GetComponentInChildren <Text>().fontSize = parentfontsize / 2;
            }


            if (someObject == null || ReferenceEquals(someObject, null) || someObject.ToString() == "null")
            {
                Debug.Log("in here mofo");
                inspectable.GetComponentInChildren <Text>().fontSize /= 2;
                instantiatedelement.GetComponent <Image>().color      = Color.red;
            }

            //if the newly instantiated element is a list lets open it up by sending a click event
            if (InspectorVisualization.IsList(someObject))
            {
                Debug.Log("the item was a list so open it");
                ExecuteEvents.Execute <IPointerClickHandler>(instantiatedelement, new PointerEventData(EventSystem.current), ExecuteEvents.pointerClickHandler);
            }

            // when the text is updated the layout is regenerated, this might happen on the next frame
            // and so lines need to be drawn, afer that, it's best if the visualizations are hooked to an event
            // watching for changes on the node or the
            inspectable.UpdateText();
            inspectable.UpdateVisualization();
            return(instantiatedelement);
        }