public static string GenerateInputCodeStub(RecordedGameObjectData obj, bool anyAssertions, string assert)
        {
            StringBuilder stub   = new StringBuilder();
            string        parent = string.Format("<div class='code_line'><span class='variable'>parentObject</span> = <span class='object_declaration'>Q</span>.driver.Find(By.Name, <span class='string_text'>\"{0}\"</span>, false);</div>", obj.TopLevelParentName);

            if (_lastParentObjectSet != parent)
            {
                if (obj.ParentNames.Count <= MAX_NUM_PARENTNAMES_BEFORE_DRILLDOWN)
                {
                    stub.AppendLine(parent);
                }
                _lastParentObjectSet = parent;
            }
            else
            {
                parent = string.Empty;
            }

            string midLevelParentName = string.Empty;

            if (obj.ParentNames.Count > MAX_NUM_PARENTNAMES_BEFORE_DRILLDOWN)
            {
                if (!string.IsNullOrEmpty(parent))
                {
                    stub.AppendLine(parent);
                }
                midLevelParentName = obj.ParentNames[(int)Math.Round((double)obj.ParentNames.Count / 2, 0)];
                if (midLevelParentName != obj.TopLevelParentName && _lastMidLevelObjectSet != midLevelParentName)
                {
                    _lastMidLevelObjectSet = midLevelParentName;
                    stub.AppendLine(string.Format("<div class='code_line'><span class='variable'>middleLevelObject</span> = <span class='object_declaration'>Q</span>.driver.FindIn(<span class='variable'>parentObject</span>, By.Name, <span class='string_text'>\"{0}\"</span>, false);</div>", midLevelParentName));
                }
            }

            string currentObjectFind = string.Format("<span class='object_declaration'>Q</span>.driver.FindIn(<span class='variable'>{0}</span>, By.Name, <span class='string_text'>\"{1}\"</span>)", obj.ParentNames.Count > MAX_NUM_PARENTNAMES_BEFORE_DRILLDOWN && midLevelParentName != obj.TopLevelParentName? "middleLevelObject" : "parentObject", obj.Name);

            if (anyAssertions)
            {
                string current = string.Format("<div class='code_line'><span class='variable'>currentObject</span> = {0};</div>", currentObjectFind);
                if (_lastCurrentObjectSet != current)
                {
                    _lastCurrentObjectSet = current;
                    stub.AppendLine(_lastCurrentObjectSet);
                }
            }
            if (!string.IsNullOrEmpty(assert))
            {
                stub.AppendLine(assert);
            }

            string inputClassName = string.Empty;

            for (int d = 0; d < obj.Components.Count; d++)
            {
                if (obj.Components[d] == "InputField")
                {
                    inputClassName = "InputField";
                    break;
                }
                else if (GameSpecificActableTypes.FindAll(x => x.Key.Name == obj.Components[d] && x.Value == ActableTypes.Input).Any())
                {
                    inputClassName = GameSpecificActableTypes.Find(x => x.Key.Name == obj.Components[d] && x.Value == ActableTypes.Input).Key.Name;
                    break;
                }
                else if (GameMaster.AdditionalAssetsAll.FindAll(x => x.Key.Name == obj.Components[d] && x.Value == ActableTypes.Input).Any())
                {
                    inputClassName = GameMaster.AdditionalAssetsAll.Find(x => x.Key.Name == obj.Components[d] && x.Value == ActableTypes.Input).Key.Name;
                    break;
                }
            }

            stub.AppendLine(string.Format("<div class='code_line'><span class='value'>yield return StartCoroutine</span>(<span class='object_declaration'>Q</span>.driver.SendKeys({0}.GetComponent&lt;<span class='variable'>{1}</span>&gt;(), {2}));</div>", anyAssertions ? "currentObject" : currentObjectFind, inputClassName, obj.RandomStringLength > 0 ? string.Format("<span class='object_declaration'>Q</span>.help.RandomString({0}, {1})", obj.RandomStringLength.ToString(), obj.RandomStringAllowSpecialCharacters ? "false" : "true") : string.Format("<span class='string_text'>\"{0}\"</span>", obj.TextValue)));
            return(_lastAddedStep = stub.ToString());
        }
        /// <summary>
        /// Remove Automation listener from all objects.
        /// </summary>
        public static void AutomationRelevantActionTaken(AutomationListener listener)
        {
            List <Component> components = listener.gameObject.GetComponents <Component>().ToList();

            //Ignore if no components.
            if (!components.Any())
            {
                return;
            }

            RecordedGameObjectData data = new RecordedGameObjectData();;

            data.Name = listener.gameObject.name.Replace("(Clone)", string.Empty);
            KeyValuePair <string, List <string> > parents = GetTopLevelParentObject(listener.gameObject);

            data.ParentNames        = parents.Value;
            data.TopLevelParentName = parents.Key;
            data.Tag = listener.gameObject.tag;
            data.Components.Add("GameObject");
            data.Components.AddRange(listener.gameObject.GetComponents <Component>().ToList().ToListOfNames());
            data.AsComponent = data.Components.FindIndexOf("GameObject");

            List <KeyValuePair <Type, ActableTypes> > matches = GameSpecificActableTypes.FindAll(x => data.Components.Contains(x.Key.Name));

            Button b = listener.gameObject.GetComponent <Button>();
            Toggle t = listener.gameObject.GetComponent <Toggle>();

            if (b != null || t != null || matches.FindAll(x => x.Value == ActableTypes.Clickable).Any())
            {
                if (b != null)
                {
                    data.AsComponent = data.Components.FindIndexOf("Button");
                }
                else if (t != null)
                {
                    data.AsComponent = data.Components.FindIndexOf("Toggle");
                }
                else
                {
                    data.AsComponent = data.Components.FindIndexOf(matches.Find(x => x.Value == ActableTypes.Clickable).Key.Name);
                }
                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Clickable;
                RecordedActions.Add(data);
                return;
            }

            if (components.FindAll(z => z.GetType().Name.ToLower().ContainsOrEquals("collider")).Any())
            {
                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Clickable;
                RecordedActions.Add(data);
                return;
            }

            ScrollRect sr = listener.gameObject.GetComponent <ScrollRect>();

            if (sr != null || matches.FindAll(x => x.Value == ActableTypes.Scroll).Any())
            {
                if (sr != null)
                {
                    data.AsComponent = data.Components.FindAll(x => x == "ScrollRect").Any() ? data.Components.FindIndexOf("ScrollRect") : data.Components.FindIndexOf("ScrollRectEx");
                }
                else
                {
                    data.AsComponent = data.Components.FindIndexOf(matches.Find(x => x.Value == ActableTypes.Scroll).Key.Name);
                }

                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Scroll;
                data.InitialScrollPosition = sr.verticalScrollbar == null ? (sr.horizontalScrollbar == null ? 0 : sr.horizontalScrollbar.value) : sr.verticalScrollbar.value;
                data.Duration = 1;
                RecordedActions.Add(data);
                return;
            }

            InputField i = listener.gameObject.GetComponent <InputField>();

            if (i != null || matches.FindAll(x => x.Value == ActableTypes.Input).Any())
            {
                data.AsComponent = data.Components.FindIndexOf("InputField");
                data.ID          = CurrentStepID++;
                data.Action      = ActableTypes.Input;
                RecordedActions.Add(data);
                return;
            }

            for (int a = 0; a < GameMaster.AdditionalAssetsAll.Count; a++)
            {
                Component c = listener.gameObject.GetComponent(GameMaster.AdditionalAssetsAll[a].Key.Name);
                if (c != null || matches.FindAll(x => x.Value == GameSpecificActableTypes[a].Value).Any())
                {
                    data.AsComponent = data.Components.FindIndexOf(GameMaster.AdditionalAssetsAll[a].Key.Name);
                    data.ID          = CurrentStepID++;
                    data.Action      = ActableTypes.Input;
                    RecordedActions.Add(data);
                    return;
                }
            }

            for (int ty = 0; ty < GameSpecificActableTypes.Count; ty++)
            {
                Component c = listener.gameObject.GetComponent(GameSpecificActableTypes[ty].Key.Name);
                if (c != null || matches.FindAll(x => x.Value == GameSpecificActableTypes[ty].Value).Any())
                {
                    data.AsComponent = data.Components.FindIndexOf(GameSpecificActableTypes[ty].Key.Name);
                    data.ID          = CurrentStepID++;
                    data.Action      = ActableTypes.Input;
                    RecordedActions.Add(data);
                    return;
                }
            }

            /*TODO: Update around text clickable for floating assertions.
             * Text txt = listener.gameObject.GetComponent<Text>();
             * TMPro.TextMeshProUGUI tmp = listener.gameObject.GetComponent<TMPro.TextMeshProUGUI>();
             * if(txt != null || tmp != null) {
             *
             * data.AsComponent = txt != null ? data.Components.FindIndexOf("Text") : data.Components.FindIndexOf("TextMeshProUGUI");
             * data.ID = CurrentStepID++;
             * data.Action = ActableTypes.TextForAssert;
             * RecordingAssertionData assert = new RecordingAssertionData(CurrentAssertionID++);
             * assert.Type = AssertionType.IsTrue;
             * assert.AssertionIsTrue = AssertionIsTrue.TextContainsOrEquals;
             * RecordedActions.Add(data);
             * return;
             *
             * }
             */
        }