static UserAssetTokenAction? SelectInteractive(ref QueryToken token, QueryDescription qd, SubTokensOptions options, bool allowRemoveToken, bool allowReGenerate)
        {
            var top = Console.CursorTop;

            try
            {
                if (Console.Out == null)
                    throw new InvalidOperationException("Impossible to synchronize without interactive Console");

                var subTokens = token.SubTokens(qd, options).OrderBy(a => a.Parent != null).ThenBy(a => a.Key).ToList();

                int startingIndex = 0;

                SafeConsole.WriteLineColor(ConsoleColor.Cyan, "  " + token.Try(a => a.FullKey()));

                bool isRoot = token == null;

            retry:
                int maxElements = Console.LargestWindowHeight - 11;

                subTokens.Skip(startingIndex).Take(maxElements)
                    .Select((s, i) => "- {1,2}: {2} ".FormatWith(i + " ", i + startingIndex, ((isRoot && s.Parent != null) ? "-" : "") + s.Key)).ToConsole();
                Console.WriteLine();

                int remaining = subTokens.Count - startingIndex - maxElements;
                if (remaining > 0)
                    SafeConsole.WriteLineColor(ConsoleColor.White, "- +: Show more values ({0} remaining)", remaining);

                if (token != null)
                {
                    SafeConsole.WriteLineColor(ConsoleColor.White, "- b: Back");
                    SafeConsole.WriteLineColor(ConsoleColor.Green, "- c: Confirm");
                }

                SafeConsole.WriteLineColor(ConsoleColor.Yellow, "- s: Skip entity");

                if (allowRemoveToken)
                    SafeConsole.WriteLineColor(ConsoleColor.DarkRed, "- r: Remove token");

                if (allowReGenerate)
                    SafeConsole.WriteLineColor(ConsoleColor.Magenta, "- g: Generate from default template");


                SafeConsole.WriteLineColor(ConsoleColor.Red, "- d: Delete entity");

                while (true)
                {
                    string answer = Console.ReadLine();

                    if (answer == null)
                        throw new InvalidOperationException("Impossible to synchronize interactively without Console");

                    answer = answer.ToLower();

                    if (answer == "+" && remaining > 0)
                    {
                        startingIndex += maxElements;
                        goto retry;
                    }

                    if (answer == "s")
                        return UserAssetTokenAction.SkipEntity;

                    if (answer == "r" && allowRemoveToken)
                        return UserAssetTokenAction.RemoveToken;

                    if (answer == "d")
                        return UserAssetTokenAction.DeleteEntity;

                    if (answer == "g")
                        return UserAssetTokenAction.ReGenerateEntity;

                    if (token != null)
                    {
                        if (answer == "c")
                            return UserAssetTokenAction.Confirm;

                        if (answer == "b")
                        {
                            token = token.Parent;
                            return null;
                        }
                    }

                    int option = 0;
                    if (int.TryParse(answer, out option))
                    {
                        token = subTokens[option];
                        return null;
                    }

                    Console.WriteLine("Error");
                }
            }
            finally
            {
                Clean(top, Console.CursorTop);
            }
        }