private static void ButtonOnGUI(WidgetRow widgetRow)
        {
            if (widgetRow.ButtonIcon(ConsoleTexturePool.Get("Console/PythonConsoleOpen"), "Open the Python console."))
            {
                //button was clicked
                var inst = Instance;
                List <Verse.Window> windowstack_windows =
                    (List <Window>) typeof(WindowStack).InvokeMember("windows", BindingFlags.GetField
                                                                     | BindingFlags.Instance | BindingFlags.NonPublic, null, Find.WindowStack, null);
                List <ConsoleWindow> visible_windows =
                    windowstack_windows.FindAll(w => typeof(ConsoleWindow).IsInstanceOfType(w))
                    .Cast <ConsoleWindow>().ToList();

                if (visible_windows.Count > 0)
                {
                    //put all visible console windows into storage
                    foreach (Window w in visible_windows)
                    {
                        Find.WindowStack.TryRemove(w, false);
                    }
                    inst.windows_storage.AddRange(visible_windows);
                }
                else
                {
                    if (inst.windows_storage.Count > 0)
                    {
                        //move stored windows back to WindowStack
                        foreach (Window w in inst.windows_storage)
                        {
                            Find.WindowStack.Add(w);
                        }
                        inst.windows_storage.Clear();
                    }
                    else
                    {
                        //there are no console windows at all; make one
                        Find.WindowStack.Add(new ConsoleWindow());
                    }
                }
            }
        }
        public override void DoWindowContents(Rect borderRect)
        {
            float buttons_left;
            {
                var button_rects = Enumerable.Range(0, int.MaxValue).Select(delegate(int x) {
                    float right = borderRect.width - 32f - (32f * x);
                    return(new Rect(right - 24f, 3f, 24f, 24f));
                }).GetEnumerator();

                //duplicate window button
                button_rects.MoveNext();
                if (Widgets.ButtonImage(button_rects.Current, ConsoleTexturePool.Get("Console/DuplicateConsoleWindowButton")))
                {
                    //button pressed
                    Find.WindowStack.Add(new ConsoleWindow(console.target));
                }

                //new window button
                button_rects.MoveNext();
                if (Widgets.ButtonImage(button_rects.Current, ConsoleTexturePool.Get("Console/NewConsoleWindowButton")))
                {
                    MakeNewWindowMenu();
                }

                buttons_left = button_rects.Current.xMin;
            }

            Rect consoleRect = new Rect(borderRect);

            consoleRect.yMin += titlebarHeight;
            consoleRect.yMax -= statusbarHeight;
            consoleRect       = consoleRect.ContractedBy(consoleMargin);

            int id = GUIUtility.GetControlID(controlIDHint, FocusType.Keyboard, consoleRect);

            switch (Event.current.type)
            {
            case EventType.Repaint:
                //title
                Rect titleRect  = new Rect(8f, 2f, buttons_left - 8f, titlebarHeight - 2f);
                var  titleStyle = new GUIStyle(Text.fontStyles[(int)GameFont.Small]);
                titleStyle.alignment = TextAnchor.MiddleLeft;
                titleStyle.wordWrap  = false;
                GUI.color            = new Color(1f, 1f, 1f);
                GUI.Label(titleRect, console.title, titleStyle);
                //console
                DrawConsole(consoleRect);
                break;

            case EventType.MouseDown:
                GUIUtility.keyboardControl = id;
                break;

            case EventType.KeyDown:
                if (GUIUtility.keyboardControl != id)
                {
                    break;
                }
                bool use = true;
                switch (Event.current.keyCode)
                {
                case KeyCode.Return:
                case KeyCode.KeypadEnter:
                    console.ProcessInput();
                    break;

                case KeyCode.Delete:
                    console.DeleteChar(false);
                    break;

                case KeyCode.Backspace:
                    console.DeleteChar(true);
                    break;

                case KeyCode.LeftArrow:
                    console.EditorCursor--;
                    break;

                case KeyCode.RightArrow:
                    console.EditorCursor++;
                    break;

                case KeyCode.UpArrow:
                    console.CurrentInputIndex--;
                    break;

                case KeyCode.DownArrow:
                    console.CurrentInputIndex++;
                    break;

                default:
                    char c = Event.current.character;
                    if (ConsoleTextureCacheRenderer.UnityFont.HasCharacter(c))
                    {
                        console.InputChar(c);
                    }
                    else if (c == '\0')
                    {
                    }
                    else
                    {
                        Log.Message(((int)Event.current.character).ToString()); use = false;
                    }
                    break;
                }
                if (use)
                {
                    Event.current.Use();
                }
                break;
            }
        }