/// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <object> elementObjects = new List <object>();
            List <KeyValuePair <string, UIElement_Goo> > allElements = new List <KeyValuePair <string, UIElement_Goo> >();
            List <string> elementFilters = new List <string>();



            if (!DA.GetDataList <object>("Elements", elementObjects))
            {
                return;
            }
            DA.GetDataList <string>("Name Filter(s)", elementFilters);



            //the elements to listen to
            List <UIElement> filteredElements = new List <UIElement>();



            //decide whether to populate the dictionary, or just populate filteredElements directly.
            foreach (object o in elementObjects)
            {
                UIElement elem = null;
                switch (o.GetType().ToString())
                {
                case "HumanUI.UIElement_Goo":
                    UIElement_Goo goo = o as UIElement_Goo;
                    elem = goo.element as UIElement;
                    filteredElements.Add(elem);
                    break;

                case "Grasshopper.Kernel.Types.GH_ObjectWrapper":
                    GH_ObjectWrapper wrapper = o as GH_ObjectWrapper;
                    KeyValuePair <string, UIElement_Goo> kvp = (KeyValuePair <string, UIElement_Goo>)wrapper.Value;
                    allElements.Add(kvp);
                    break;

                default:
                    break;
                }
            }

            if (allElements.Count > 0) //if we've been getting keyvaluepairs and need to filter
            {
                //create a dictionary for filtering
                Dictionary <string, UIElement_Goo> elementDict = allElements.ToDictionary(pair => pair.Key, pair => pair.Value);



                //filter the dictionary
                foreach (string fil in elementFilters)
                {
                    filteredElements.Add(elementDict[fil].element);
                }
                //if there are no filters, include all values.
                if (elementFilters.Count == 0)
                {
                    foreach (UIElement_Goo u in elementDict.Values)
                    {
                        filteredElements.Add(u.element);
                    }
                }
            }

            //remove all events from previously "evented" elements
            foreach (UIElement u in eventedElements)
            {
                RemoveEvents(u);
            }
            eventedElements.Clear();


            //extract base elements
            List <UIElement> elementsToListen = new List <UIElement>();

            HUI_Util.extractBaseElements(filteredElements, elementsToListen);



            //retrieve element values
            GH_Structure <IGH_Goo>    values  = new GH_Structure <IGH_Goo>();
            GH_Structure <GH_Integer> indsOut = new GH_Structure <GH_Integer>();
            int i = 0;

            foreach (UIElement u in elementsToListen)
            {
                object      value   = HUI_Util.GetElementValue(u);
                object      indices = HUI_Util.GetElementIndex(u);
                IEnumerable list    = null;
                if ((value as string) == null)
                {
                    list = value as IEnumerable;
                }
                IEnumerable indList = indices as IEnumerable;
                if (list != null)
                {
                    foreach (object thing in list)
                    {
                        values.Append(HUI_Util.GetRightType(thing), new GH_Path(i));
                    }
                }
                else
                {
                    values.Append(HUI_Util.GetRightType(value), new GH_Path(i));
                }

                if (indList != null)
                {
                    foreach (int index in indList)
                    {
                        indsOut.Append(new GH_Integer(index), new GH_Path(i));
                    }
                }
                else
                {
                    indsOut.Append(new GH_Integer((int)indices), new GH_Path(i));
                }



                //add listener events to elements
                if (AddEventsEnabled)
                {
                    eventedElements.Add(u);
                    AddEvents(u);
                }
                i++;
            }



            DA.SetDataTree(0, values);
            DA.SetDataTree(1, indsOut);
        }