//===-- IOHandler.cpp -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#ifndef LLDB_DISABLE_CURSES
#include <curses.h>
#include <panel.h>
#endif

// C++ Includes
#if defined(__APPLE__)
#include <deque>
#endif
#include <string>

// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectRegister.h"
#ifndef LLDB_DISABLE_LIBEDIT
#include "lldb/Host/Editline.h"
#endif
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/ThreadPlan.h"



using namespace lldb;
using namespace lldb_private;

IOHandler::IOHandler (Debugger &debugger, IOHandler::Type type) :
    IOHandler (debugger,
               type,
               StreamFileSP(),  // Adopt STDIN from top input reader
               StreamFileSP(),  // Adopt STDOUT from top input reader
               StreamFileSP(),  // Adopt STDERR from top input reader
               0)               // Flags
{
}

IOHandler::IOHandler (Debugger &debugger,
                      IOHandler::Type type,
                      const lldb::StreamFileSP &input_sp,
                      const lldb::StreamFileSP &output_sp,
                      const lldb::StreamFileSP &error_sp,
                      uint32_t flags) :
    m_debugger (debugger),
    m_input_sp (input_sp),
    m_output_sp (output_sp),
    m_error_sp (error_sp),
    m_popped (false),
    m_flags (flags),
    m_type (type),
    m_user_data (NULL),
    m_done (false),
    m_active (false)
{
    // If any files are not specified, then adopt them from the top input reader.
    if (!m_input_sp || !m_output_sp || !m_error_sp)
        debugger.AdoptTopIOHandlerFilesIfInvalid (m_input_sp,
                                                  m_output_sp,
                                                  m_error_sp);
}

IOHandler::~IOHandler() = default;

int
IOHandler::GetInputFD()
{
    if (m_input_sp)
        return m_input_sp->GetFile().GetDescriptor();
    return -1;
}

int
IOHandler::GetOutputFD()
{
    if (m_output_sp)
        return m_output_sp->GetFile().GetDescriptor();
    return -1;
}

int
IOHandler::GetErrorFD()
{
    if (m_error_sp)
        return m_error_sp->GetFile().GetDescriptor();
    return -1;
}

FILE *
IOHandler::GetInputFILE()
{
    if (m_input_sp)
        return m_input_sp->GetFile().GetStream();
    return NULL;
}

FILE *
IOHandler::GetOutputFILE()
{
    if (m_output_sp)
        return m_output_sp->GetFile().GetStream();
    return NULL;
}

FILE *
IOHandler::GetErrorFILE()
{
    if (m_error_sp)
        return m_error_sp->GetFile().GetStream();
    return NULL;
}

StreamFileSP &
IOHandler::GetInputStreamFile()
{
    return m_input_sp;
}

StreamFileSP &
IOHandler::GetOutputStreamFile()
{
    return m_output_sp;
}

StreamFileSP &
IOHandler::GetErrorStreamFile()
{
    return m_error_sp;
}

bool
IOHandler::GetIsInteractive ()
{
    return GetInputStreamFile()->GetFile().GetIsInteractive ();
}

bool
IOHandler::GetIsRealTerminal ()
{
    return GetInputStreamFile()->GetFile().GetIsRealTerminal();
}

void
IOHandler::SetPopped (bool b)
{
    m_popped.SetValue(b, eBroadcastOnChange);
}

void
IOHandler::WaitForPop ()
{
    m_popped.WaitForValueEqualTo(true);
}

void
IOHandlerStack::PrintAsync (Stream *stream, const char *s, size_t len)
{
    if (stream)
    {
        Mutex::Locker locker (m_mutex);
        if (m_top)
            m_top->PrintAsync (stream, s, len);
    }
}

IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
                                    const char *prompt,
                                    bool default_response) :
    IOHandlerEditline(debugger,
                      IOHandler::Type::Confirm,
                      NULL,     // NULL editline_name means no history loaded/saved
                      NULL,     // No prompt
                      NULL,     // No continuation prompt
                      false,    // Multi-line
                      false,    // Don't colorize the prompt (i.e. the confirm message.)
                      0,
                      *this),
    m_default_response (default_response),
    m_user_response (default_response)
{
    StreamString prompt_stream;
    prompt_stream.PutCString(prompt);
    if (m_default_response)
        prompt_stream.Printf(": [Y/n] ");
    else
        prompt_stream.Printf(": [y/N] ");
    
    SetPrompt (prompt_stream.GetString().c_str());
    
}

IOHandlerConfirm::~IOHandlerConfirm() = default;

int
IOHandlerConfirm::IOHandlerComplete (IOHandler &io_handler,
                                     const char *current_line,
                                     const char *cursor,
                                     const char *last_char,
                                     int skip_first_n_matches,
                                     int max_matches,
                                     StringList &matches)
{
    if (current_line == cursor)
    {
        if (m_default_response)
        {
            matches.AppendString("y");
        }
        else
        {
            matches.AppendString("n");
        }
    }
    return matches.GetSize();
}

void
IOHandlerConfirm::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
{
    if (line.empty())
    {
        // User just hit enter, set the response to the default
        m_user_response = m_default_response;
        io_handler.SetIsDone(true);
        return;
    }

    if (line.size() == 1)
    {
        switch (line[0])
        {
            case 'y':
            case 'Y':
                m_user_response = true;
                io_handler.SetIsDone(true);
                return;
            case 'n':
            case 'N':
                m_user_response = false;
                io_handler.SetIsDone(true);
                return;
            default:
                break;
        }
    }

    if (line == "yes" || line == "YES" || line == "Yes")
    {
        m_user_response = true;
        io_handler.SetIsDone(true);
    }
    else if (line == "no" || line == "NO" || line == "No")
    {
        m_user_response = false;
        io_handler.SetIsDone(true);
    }
}

int
IOHandlerDelegate::IOHandlerComplete (IOHandler &io_handler,
                                      const char *current_line,
                                      const char *cursor,
                                      const char *last_char,
                                      int skip_first_n_matches,
                                      int max_matches,
                                      StringList &matches)
{
    switch (m_completion)
    {
    case Completion::None:
        break;

    case Completion::LLDBCommand:
        return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion (current_line,
                                                                                  cursor,
                                                                                  last_char,
                                                                                  skip_first_n_matches,
                                                                                  max_matches,
                                                                                  matches);

    case Completion::Expression:
        {
            bool word_complete = false;
            const char *word_start = cursor;
            if (cursor > current_line)
                --word_start;
            while (word_start > current_line && !isspace(*word_start))
                --word_start;
            CommandCompletions::InvokeCommonCompletionCallbacks (io_handler.GetDebugger().GetCommandInterpreter(),
                                                                 CommandCompletions::eVariablePathCompletion,
                                                                 word_start,
                                                                 skip_first_n_matches,
                                                                 max_matches,
                                                                 NULL,
                                                                 word_complete,
                                                                 matches);
            
            size_t num_matches = matches.GetSize();
            if (num_matches > 0)
            {
                std::string common_prefix;
                matches.LongestCommonPrefix (common_prefix);
                const size_t partial_name_len = strlen(word_start);
                
                // If we matched a unique single command, add a space...
                // Only do this if the completer told us this was a complete word, however...
                if (num_matches == 1 && word_complete)
                {
                    common_prefix.push_back(' ');
                }
                common_prefix.erase (0, partial_name_len);
                matches.InsertStringAtIndex(0, std::move(common_prefix));
            }
            return num_matches;
        }
        break;
    }
    
    return 0;
}

IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
                                      IOHandler::Type type,
                                      const char *editline_name, // Used for saving history files
                                      const char *prompt,
                                      const char *continuation_prompt,
                                      bool multi_line,
                                      bool color_prompts,
                                      uint32_t line_number_start,
                                      IOHandlerDelegate &delegate) :
    IOHandlerEditline(debugger,
                      type,
                      StreamFileSP(), // Inherit input from top input reader
                      StreamFileSP(), // Inherit output from top input reader
                      StreamFileSP(), // Inherit error from top input reader
                      0,              // Flags
                      editline_name,  // Used for saving history files
                      prompt,
                      continuation_prompt,
                      multi_line,
                      color_prompts,
                      line_number_start,
                      delegate)
{
}

IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
                                      IOHandler::Type type,
                                      const lldb::StreamFileSP &input_sp,
                                      const lldb::StreamFileSP &output_sp,
                                      const lldb::StreamFileSP &error_sp,
                                      uint32_t flags,
                                      const char *editline_name, // Used for saving history files
                                      const char *prompt,
                                      const char *continuation_prompt,
                                      bool multi_line,
                                      bool color_prompts,
                                      uint32_t line_number_start,
                                      IOHandlerDelegate &delegate) :
    IOHandler (debugger, type, input_sp, output_sp, error_sp, flags),
#ifndef LLDB_DISABLE_LIBEDIT
    m_editline_ap (),
#endif
    m_delegate (delegate),
    m_prompt (),
    m_continuation_prompt(),
    m_current_lines_ptr (NULL),
    m_base_line_number (line_number_start),
    m_curr_line_idx (UINT32_MAX),
    m_multi_line (multi_line),
    m_color_prompts (color_prompts),
    m_interrupt_exits (true),
    m_editing (false)
{
    SetPrompt(prompt);

#ifndef LLDB_DISABLE_LIBEDIT
    bool use_editline = false;
    
    use_editline = m_input_sp->GetFile().GetIsRealTerminal();

    if (use_editline)
    {
        m_editline_ap.reset(new Editline (editline_name,
                                          GetInputFILE (),
                                          GetOutputFILE (),
                                          GetErrorFILE (),
                                          m_color_prompts));
        m_editline_ap->SetIsInputCompleteCallback (IsInputCompleteCallback, this);
        m_editline_ap->SetAutoCompleteCallback (AutoCompleteCallback, this);
        // See if the delegate supports fixing indentation
        const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
        if (indent_chars)
        {
            // The delegate does support indentation, hook it up so when any indentation
            // character is typed, the delegate gets a chance to fix it
            m_editline_ap->SetFixIndentationCallback (FixIndentationCallback, this, indent_chars);
        }
    }
#endif
    SetBaseLineNumber (m_base_line_number);
    SetPrompt(prompt ? prompt : "");
    SetContinuationPrompt(continuation_prompt);    
}

IOHandlerEditline::~IOHandlerEditline ()
{
#ifndef LLDB_DISABLE_LIBEDIT
    m_editline_ap.reset();
#endif
}

void
IOHandlerEditline::Activate ()
{
    IOHandler::Activate();
    m_delegate.IOHandlerActivated(*this);
}

void
IOHandlerEditline::Deactivate ()
{
    IOHandler::Deactivate();
    m_delegate.IOHandlerDeactivated(*this);
}

bool
IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
    {
        return m_editline_ap->GetLine (line, interrupted);
    }
    else
    {
#endif
        line.clear();

        FILE *in = GetInputFILE();
        if (in)
        {
            if (GetIsInteractive())
            {
                const char *prompt = NULL;
                
                if (m_multi_line && m_curr_line_idx > 0)
                    prompt = GetContinuationPrompt();
                
                if (prompt == NULL)
                    prompt = GetPrompt();
                
                if (prompt && prompt[0])
                {
                    FILE *out = GetOutputFILE();
                    if (out)
                    {
                        ::fprintf(out, "%s", prompt);
                        ::fflush(out);
                    }
                }
            }
            char buffer[256];
            bool done = false;
            bool got_line = false;
            m_editing = true;
            while (!done)
            {
                if (fgets(buffer, sizeof(buffer), in) == NULL)
                {
                    const int saved_errno = errno;
                    if (feof(in))
                        done = true;
                    else if (ferror(in))
                    {
                        if (saved_errno != EINTR)
                            done = true;
                    }
                }
                else
                {
                    got_line = true;
                    size_t buffer_len = strlen(buffer);
                    assert (buffer[buffer_len] == '\0');
                    char last_char = buffer[buffer_len-1];
                    if (last_char == '\r' || last_char == '\n')
                    {
                        done = true;
                        // Strip trailing newlines
                        while (last_char == '\r' || last_char == '\n')
                        {
                            --buffer_len;
                            if (buffer_len == 0)
                                break;
                            last_char = buffer[buffer_len-1];
                        }
                    }
                    line.append(buffer, buffer_len);
                }
            }
            m_editing = false;
            // We might have gotten a newline on a line by itself
            // make sure to return true in this case.
            return got_line;
        }
        else
        {
            // No more input file, we are done...
            SetIsDone(true);
        }
        return false;
#ifndef LLDB_DISABLE_LIBEDIT
    }
#endif
}


#ifndef LLDB_DISABLE_LIBEDIT
bool
IOHandlerEditline::IsInputCompleteCallback (Editline *editline,
                                          StringList &lines,
                                          void *baton)
{
    IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
    return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader, lines);
}

int
IOHandlerEditline::FixIndentationCallback (Editline *editline,
                                           const StringList &lines,
                                           int cursor_position,
                                           void *baton)
{
    IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
    return editline_reader->m_delegate.IOHandlerFixIndentation(*editline_reader, lines, cursor_position);
}

int
IOHandlerEditline::AutoCompleteCallback (const char *current_line,
                                         const char *cursor,
                                         const char *last_char,
                                         int skip_first_n_matches,
                                         int max_matches,
                                         StringList &matches,
                                         void *baton)
{
    IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
    if (editline_reader)
        return editline_reader->m_delegate.IOHandlerComplete (*editline_reader,
                                                              current_line,
                                                              cursor,
                                                              last_char,
                                                              skip_first_n_matches,
                                                              max_matches,
                                                              matches);
    return 0;
}
#endif

const char *
IOHandlerEditline::GetPrompt ()
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
    {
        return m_editline_ap->GetPrompt ();
    }
    else
    {
#endif
        if (m_prompt.empty())
            return NULL;
#ifndef LLDB_DISABLE_LIBEDIT
    }
#endif
    return m_prompt.c_str();
}

bool
IOHandlerEditline::SetPrompt (const char *p)
{
    if (p && p[0])
        m_prompt = p;
    else
        m_prompt.clear();
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        m_editline_ap->SetPrompt (m_prompt.empty() ? NULL : m_prompt.c_str());
#endif
    return true;
}

const char *
IOHandlerEditline::GetContinuationPrompt ()
{
    if (m_continuation_prompt.empty())
        return NULL;
    return m_continuation_prompt.c_str();
}

void
IOHandlerEditline::SetContinuationPrompt (const char *p)
{
    if (p && p[0])
        m_continuation_prompt = p;
    else
        m_continuation_prompt.clear();

#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        m_editline_ap->SetContinuationPrompt (m_continuation_prompt.empty() ? NULL : m_continuation_prompt.c_str());
#endif
}

void
IOHandlerEditline::SetBaseLineNumber (uint32_t line)
{
    m_base_line_number = line;
}

uint32_t
IOHandlerEditline::GetCurrentLineIndex () const
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        return m_editline_ap->GetCurrentLine();
#endif
    return m_curr_line_idx;
}

bool
IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
{
    m_current_lines_ptr = &lines;
    
    bool success = false;
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
    {
        return m_editline_ap->GetLines (m_base_line_number, lines, interrupted);
    }
    else
    {
#endif
        bool done = false;
        Error error;

        while (!done)
        {
            // Show line numbers if we are asked to
            std::string line;
            if (m_base_line_number > 0 && GetIsInteractive())
            {
                FILE *out = GetOutputFILE();
                if (out)
                    ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(), GetPrompt() == NULL ? " " : "");
            }
            
            m_curr_line_idx = lines.GetSize();
            
            bool interrupted = false;
            if (GetLine(line, interrupted) && !interrupted)
            {
                lines.AppendString(line);
                done = m_delegate.IOHandlerIsInputComplete(*this, lines);
            }
            else
            {
                done = true;
            }
        }
        success = lines.GetSize() > 0;
#ifndef LLDB_DISABLE_LIBEDIT
    }
#endif
    return success;
}

// Each IOHandler gets to run until it is done. It should read data
// from the "in" and place output into "out" and "err and return
// when done.
void
IOHandlerEditline::Run ()
{
    std::string line;
    while (IsActive())
    {
        bool interrupted = false;
        if (m_multi_line)
        {
            StringList lines;
            if (GetLines (lines, interrupted))
            {
                if (interrupted)
                {
                    m_done = m_interrupt_exits;
                    m_delegate.IOHandlerInputInterrupted (*this, line);

                }
                else
                {
                    line = lines.CopyList();
                    m_delegate.IOHandlerInputComplete (*this, line);
                }
            }
            else
            {
                m_done = true;
            }
        }
        else
        {
            if (GetLine(line, interrupted))
            {
                if (interrupted)
                    m_delegate.IOHandlerInputInterrupted (*this, line);
                else
                    m_delegate.IOHandlerInputComplete (*this, line);
            }
            else
            {
                m_done = true;
            }
        }
    }
}

void
IOHandlerEditline::Cancel ()
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        m_editline_ap->Cancel ();
#endif
}

bool
IOHandlerEditline::Interrupt ()
{
    // Let the delgate handle it first
    if (m_delegate.IOHandlerInterrupt(*this))
        return true;

#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        return m_editline_ap->Interrupt();
#endif
    return false;
}

void
IOHandlerEditline::GotEOF()
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        m_editline_ap->Interrupt();
#endif
}

void
IOHandlerEditline::PrintAsync (Stream *stream, const char *s, size_t len)
{
#ifndef LLDB_DISABLE_LIBEDIT
    if (m_editline_ap)
        m_editline_ap->PrintAsync(stream, s, len);
    else
#endif
        IOHandler::PrintAsync(stream, s, len);
}

// we may want curses to be disabled for some builds
// for instance, windows
#ifndef LLDB_DISABLE_CURSES

#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/StackFrame.h"

#define KEY_RETURN   10
#define KEY_ESCAPE  27

namespace curses
{
    class Menu;
    class MenuDelegate;
    class Window;
    class WindowDelegate;
    typedef std::shared_ptr<Menu> MenuSP;
    typedef std::shared_ptr<MenuDelegate> MenuDelegateSP;
    typedef std::shared_ptr<Window> WindowSP;
    typedef std::shared_ptr<WindowDelegate> WindowDelegateSP;
    typedef std::vector<MenuSP> Menus;
    typedef std::vector<WindowSP> Windows;
    typedef std::vector<WindowDelegateSP> WindowDelegates;

#if 0
type summary add -s "x=${var.x}, y=${var.y}" curses::Point
type summary add -s "w=${var.width}, h=${var.height}" curses::Size
type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
#endif

    struct Point
    {
        int x;
        int y;
        
        Point (int _x = 0, int _y = 0) :
            x(_x),
            y(_y)
        {
        }

        void
        Clear ()
        {
            x = 0;
            y = 0;
        }
        
        Point &
        operator += (const Point &rhs)
        {
            x += rhs.x;
            y += rhs.y;
            return *this;
        }
        
        void
        Dump ()
        {
            printf ("(x=%i, y=%i)\n", x, y);
        }
    };
    
    bool operator == (const Point &lhs, const Point &rhs)
    {
        return lhs.x == rhs.x && lhs.y == rhs.y;
    }

    bool operator != (const Point &lhs, const Point &rhs)
    {
        return lhs.x != rhs.x || lhs.y != rhs.y;
    }

    struct Size
    {
        int width;
        int height;
        Size (int w = 0, int h = 0) :
            width (w),
            height (h)
        {
        }
        
        void
        Clear ()
        {
            width = 0;
            height = 0;
        }

        void
        Dump ()
        {
            printf ("(w=%i, h=%i)\n", width, height);
        }
    };
    
    bool operator == (const Size &lhs, const Size &rhs)
    {
        return lhs.width == rhs.width && lhs.height == rhs.height;
    }

    bool operator != (const Size &lhs, const Size &rhs)
    {
        return lhs.width != rhs.width || lhs.height != rhs.height;
    }

    struct Rect
    {
        Point origin;
        Size size;
        
        Rect () :
            origin(),
            size()
        {
        }
    
        Rect (const Point &p, const Size &s) :
            origin (p),
            size (s)
        {
        }
        
        void
        Clear ()
        {
            origin.Clear();
            size.Clear();
        }
        
        void
        Dump ()
        {
            printf ("(x=%i, y=%i), w=%i, h=%i)\n", origin.x, origin.y, size.width, size.height);
        }
        
        void
        Inset (int w, int h)
        {
            if (size.width > w*2)
                size.width -= w*2;
            origin.x += w;

            if (size.height > h*2)
                size.height -= h*2;
            origin.y += h;
        }

        // Return a status bar rectangle which is the last line of
        // this rectangle. This rectangle will be modified to not
        // include the status bar area.
        Rect
        MakeStatusBar ()
        {
            Rect status_bar;
            if (size.height > 1)
            {
                status_bar.origin.x = origin.x;
                status_bar.origin.y = size.height;
                status_bar.size.width = size.width;
                status_bar.size.height = 1;
                --size.height;
            }
            return status_bar;
        }

        // Return a menubar rectangle which is the first line of
        // this rectangle. This rectangle will be modified to not
        // include the menubar area.
        Rect
        MakeMenuBar ()
        {
            Rect menubar;
            if (size.height > 1)
            {
                menubar.origin.x = origin.x;
                menubar.origin.y = origin.y;
                menubar.size.width = size.width;
                menubar.size.height = 1;
                ++origin.y;
                --size.height;
            }
            return menubar;
        }

        void
        HorizontalSplitPercentage (float top_percentage, Rect &top, Rect &bottom) const
        {
            float top_height = top_percentage * size.height;
            HorizontalSplit (top_height, top, bottom);
        }

        void
        HorizontalSplit (int top_height, Rect &top, Rect &bottom) const
        {
            top = *this;
            if (top_height < size.height)
            {
                top.size.height = top_height;
                bottom.origin.x = origin.x;
                bottom.origin.y = origin.y + top.size.height;
                bottom.size.width = size.width;
                bottom.size.height = size.height - top.size.height;
            }
            else
            {
                bottom.Clear();
            }
        }
        
        void
        VerticalSplitPercentage (float left_percentage, Rect &left, Rect &right) const
        {
            float left_width = left_percentage * size.width;
            VerticalSplit (left_width, left, right);
        }

        void
        VerticalSplit (int left_width, Rect &left, Rect &right) const
        {
            left = *this;
            if (left_width < size.width)
            {
                left.size.width = left_width;
                right.origin.x = origin.x + left.size.width;
                right.origin.y = origin.y;
                right.size.width = size.width - left.size.width;
                right.size.height = size.height;
            }
            else
            {
                right.Clear();
            }
        }
    };

    bool operator == (const Rect &lhs, const Rect &rhs)
    {
        return lhs.origin == rhs.origin && lhs.size == rhs.size;
    }

    bool operator != (const Rect &lhs, const Rect &rhs)
    {
        return lhs.origin != rhs.origin || lhs.size != rhs.size;
    }

    enum HandleCharResult
    {
        eKeyNotHandled      = 0,
        eKeyHandled         = 1,
        eQuitApplication    = 2
    };
    
    enum class MenuActionResult
    {
        Handled,
        NotHandled,
        Quit    // Exit all menus and quit
    };

    struct KeyHelp
    {
        int ch;
        const char *description;
    };

    class WindowDelegate
    {
    public:
        virtual
        ~WindowDelegate() = default;

        virtual bool
        WindowDelegateDraw (Window &window, bool force)
        {
            return false; // Drawing not handled
        }
        
        virtual HandleCharResult
        WindowDelegateHandleChar (Window &window, int key)
        {
            return eKeyNotHandled;
        }
        
        virtual const char *
        WindowDelegateGetHelpText ()
        {
            return NULL;
        }

        virtual KeyHelp *
        WindowDelegateGetKeyHelp ()
        {
            return NULL;
        }
    };
    
    class HelpDialogDelegate :
        public WindowDelegate
    {
    public:
        HelpDialogDelegate (const char *text, KeyHelp *key_help_array);

        ~HelpDialogDelegate() override;

        bool
        WindowDelegateDraw (Window &window, bool force) override;
        
        HandleCharResult
        WindowDelegateHandleChar (Window &window, int key) override;
        
        size_t
        GetNumLines() const
        {
            return m_text.GetSize();
        }

        size_t
        GetMaxLineLength () const
        {
            return m_text.GetMaxStringLength();
        }

    protected:
        StringList m_text;
        int m_first_visible_line;
    };

    class Window
    {
    public:
        Window (const char *name) :
            m_name (name),
            m_window (NULL),
            m_panel (NULL),
            m_parent (NULL),
            m_subwindows (),
            m_delegate_sp (),
            m_curr_active_window_idx (UINT32_MAX),
            m_prev_active_window_idx (UINT32_MAX),
            m_delete (false),
            m_needs_update (true),
            m_can_activate (true),
            m_is_subwin (false)
        {
        }
        
        Window (const char *name, WINDOW *w, bool del = true) :
            m_name (name),
            m_window (NULL),
            m_panel (NULL),
            m_parent (NULL),
            m_subwindows (),
            m_delegate_sp (),
            m_curr_active_window_idx (UINT32_MAX),
            m_prev_active_window_idx (UINT32_MAX),
            m_delete (del),
            m_needs_update (true),
            m_can_activate (true),
            m_is_subwin (false)
        {
            if (w)
                Reset(w);
        }
        
        Window (const char *name, const Rect &bounds) :
            m_name (name),
            m_window (NULL),
            m_parent (NULL),
            m_subwindows (),
            m_delegate_sp (),
            m_curr_active_window_idx (UINT32_MAX),
            m_prev_active_window_idx (UINT32_MAX),
            m_delete (true),
            m_needs_update (true),
            m_can_activate (true),
            m_is_subwin (false)
        {
            Reset (::newwin (bounds.size.height, bounds.size.width, bounds.origin.y, bounds.origin.y));
        }
        
        virtual
        ~Window ()
        {
            RemoveSubWindows ();
            Reset ();
        }
        
        void
        Reset (WINDOW *w = NULL, bool del = true)
        {
            if (m_window == w)
                return;
            
            if (m_panel)
            {
                ::del_panel (m_panel);
                m_panel = NULL;
            }
            if (m_window && m_delete)
            {
                ::delwin (m_window);
                m_window = NULL;
                m_delete = false;
            }
            if (w)
            {
                m_window = w;
                m_panel = ::new_panel (m_window);
                m_delete = del;
            }
        }
        
        void    AttributeOn (attr_t attr)   { ::wattron (m_window, attr); }
        void    AttributeOff (attr_t attr)  { ::wattroff (m_window, attr); }
        void    Box (chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) { ::box(m_window, v_char, h_char); }
        void    Clear ()    { ::wclear (m_window); }
        void    Erase ()    { ::werase (m_window); }
        Rect    GetBounds () { return Rect (GetParentOrigin(), GetSize()); } // Get the rectangle in our parent window
        int     GetChar ()  { return ::wgetch (m_window); }
        int     GetCursorX ()     { return getcurx (m_window); }
        int     GetCursorY ()     { return getcury (m_window); }
        Rect    GetFrame ()    { return Rect (Point(), GetSize()); } // Get our rectangle in our own coordinate system
        Point   GetParentOrigin() { return Point (GetParentX(), GetParentY()); }
        Size    GetSize()         { return Size (GetWidth(), GetHeight()); }
        int     GetParentX ()     { return getparx (m_window); }
        int     GetParentY ()     { return getpary (m_window); }
        int     GetMaxX()   { return getmaxx (m_window); }
        int     GetMaxY()   { return getmaxy (m_window); }
        int     GetWidth()  { return GetMaxX(); }
        int     GetHeight() { return GetMaxY(); }
        void    MoveCursor (int x, int y) {  ::wmove (m_window, y, x); }
        void    MoveWindow (int x, int y) {  MoveWindow(Point(x,y)); }
        void    Resize (int w, int h) { ::wresize(m_window, h, w); }
        void    Resize (const Size &size) { ::wresize(m_window, size.height, size.width); }
        void    PutChar (int ch)    { ::waddch (m_window, ch); }
        void    PutCString (const char *s, int len = -1) { ::waddnstr (m_window, s, len); }
        void    Refresh ()  { ::wrefresh (m_window); }
        void    DeferredRefresh ()
        {
            // We are using panels, so we don't need to call this...
            //::wnoutrefresh(m_window);
        }
        void    SetBackground (int color_pair_idx) { ::wbkgd (m_window,COLOR_PAIR(color_pair_idx)); }
        void    UnderlineOn ()  { AttributeOn(A_UNDERLINE); }
        void    UnderlineOff () { AttributeOff(A_UNDERLINE); }

        void    PutCStringTruncated (const char *s, int right_pad)
        {
            int bytes_left = GetWidth() - GetCursorX();
            if (bytes_left > right_pad)
            {
                bytes_left -= right_pad;
                ::waddnstr (m_window, s, bytes_left);
            }
        }

        void
        MoveWindow (const Point &origin)
        {
            const bool moving_window = origin != GetParentOrigin();
            if (m_is_subwin && moving_window)
            {
                // Can't move subwindows, must delete and re-create
                Size size = GetSize();
                Reset (::subwin (m_parent->m_window,
                                 size.height,
                                 size.width,
                                 origin.y,
                                 origin.x), true);
            }
            else
            {
                ::mvwin (m_window, origin.y, origin.x);
            }
        }

        void
        SetBounds (const Rect &bounds)
        {
            const bool moving_window = bounds.origin != GetParentOrigin();
            if (m_is_subwin && moving_window)
            {
                // Can't move subwindows, must delete and re-create
                Reset (::subwin (m_parent->m_window,
                                 bounds.size.height,
                                 bounds.size.width,
                                 bounds.origin.y,
                                 bounds.origin.x), true);
            }
            else
            {
                if (moving_window)
                    MoveWindow(bounds.origin);
                Resize (bounds.size);
            }
        }

        void
        Printf (const char *format, ...)  __attribute__ ((format (printf, 2, 3)))
        {
            va_list args;
            va_start (args, format);
            vwprintw(m_window, format, args);
            va_end (args);
        }

        void
        Touch ()
        {
            ::touchwin (m_window);
            if (m_parent)
                m_parent->Touch();
        }

        WindowSP
        CreateSubWindow (const char *name, const Rect &bounds, bool make_active)
        {
            WindowSP subwindow_sp;
            if (m_window)
            {
                subwindow_sp.reset(new Window(name, ::subwin (m_window,
                                                              bounds.size.height,
                                                              bounds.size.width,
                                                              bounds.origin.y,
                                                              bounds.origin.x), true));
                subwindow_sp->m_is_subwin = true;
            }
            else
            {
                subwindow_sp.reset(new Window(name, ::newwin (bounds.size.height,
                                                              bounds.size.width,
                                                              bounds.origin.y,
                                                              bounds.origin.x), true));
                subwindow_sp->m_is_subwin = false;
            }
            subwindow_sp->m_parent = this;
            if (make_active)
            {
                m_prev_active_window_idx = m_curr_active_window_idx;
                m_curr_active_window_idx = m_subwindows.size();
            }
            m_subwindows.push_back(subwindow_sp);
            ::top_panel (subwindow_sp->m_panel);
            m_needs_update = true;
            return subwindow_sp;
        }
        
        bool
        RemoveSubWindow (Window *window)
        {
            Windows::iterator pos, end = m_subwindows.end();
            size_t i = 0;
            for (pos = m_subwindows.begin(); pos != end; ++pos, ++i)
            {
                if ((*pos).get() == window)
                {
                    if (m_prev_active_window_idx == i)
                        m_prev_active_window_idx = UINT32_MAX;
                    else if (m_prev_active_window_idx != UINT32_MAX && m_prev_active_window_idx > i)
                        --m_prev_active_window_idx;

                    if (m_curr_active_window_idx == i)
                        m_curr_active_window_idx = UINT32_MAX;
                    else if (m_curr_active_window_idx != UINT32_MAX && m_curr_active_window_idx > i)
                        --m_curr_active_window_idx;
                    window->Erase();
                    m_subwindows.erase(pos);
                    m_needs_update = true;
                    if (m_parent)
                        m_parent->Touch();
                    else
                        ::touchwin (stdscr);
                    return true;
                }
            }
            return false;
        }
        
        WindowSP
        FindSubWindow (const char *name)
        {
            Windows::iterator pos, end = m_subwindows.end();
            size_t i = 0;
            for (pos = m_subwindows.begin(); pos != end; ++pos, ++i)
            {
                if ((*pos)->m_name.compare(name) == 0)
                    return *pos;
            }
            return WindowSP();
        }
        
        void
        RemoveSubWindows ()
        {
            m_curr_active_window_idx = UINT32_MAX;
            m_prev_active_window_idx = UINT32_MAX;
            for (Windows::iterator pos = m_subwindows.begin();
                 pos != m_subwindows.end();
                 pos = m_subwindows.erase(pos))
            {
                (*pos)->Erase();
            }
            if (m_parent)
                m_parent->Touch();
            else
                ::touchwin (stdscr);
        }

        WINDOW *
        get()
        {
            return m_window;
        }

        operator WINDOW *()
        {
            return m_window;
        }
        
        //----------------------------------------------------------------------
        // Window drawing utilities
        //----------------------------------------------------------------------
        void
        DrawTitleBox (const char *title, const char *bottom_message = NULL)
        {
            attr_t attr = 0;
            if (IsActive())
                attr = A_BOLD | COLOR_PAIR(2);
            else
                attr = 0;
            if (attr)
                AttributeOn(attr);

            Box();
            MoveCursor(3, 0);
            
            if (title && title[0])
            {
                PutChar ('<');
                PutCString (title);
                PutChar ('>');
            }
            
            if (bottom_message && bottom_message[0])
            {
                int bottom_message_length = strlen(bottom_message);
                int x = GetWidth() - 3 - (bottom_message_length + 2);
                
                if (x > 0)
                {
                    MoveCursor (x, GetHeight() - 1);
                    PutChar ('[');
                    PutCString(bottom_message);
                    PutChar (']');
                }
                else
                {
                    MoveCursor (1, GetHeight() - 1);
                    PutChar ('[');
                    PutCStringTruncated (bottom_message, 1);
                }
            }
            if (attr)
                AttributeOff(attr);
            
        }

        virtual void
        Draw (bool force)
        {
            if (m_delegate_sp && m_delegate_sp->WindowDelegateDraw (*this, force))
                return;

            for (auto &subwindow_sp : m_subwindows)
                subwindow_sp->Draw(force);
        }

        bool
        CreateHelpSubwindow ()
        {
            if (m_delegate_sp)
            {
                const char *text = m_delegate_sp->WindowDelegateGetHelpText ();
                KeyHelp *key_help = m_delegate_sp->WindowDelegateGetKeyHelp ();
                if ((text && text[0]) || key_help)
                {
                    std::auto_ptr<HelpDialogDelegate> help_delegate_ap(new HelpDialogDelegate(text, key_help));
                    const size_t num_lines = help_delegate_ap->GetNumLines();
                    const size_t max_length = help_delegate_ap->GetMaxLineLength();
                    Rect bounds = GetBounds();
                    bounds.Inset(1, 1);
                    if (max_length + 4 < static_cast<size_t>(bounds.size.width))
                    {
                        bounds.origin.x += (bounds.size.width - max_length + 4)/2;
                        bounds.size.width = max_length + 4;
                    }
                    else
                    {
                        if (bounds.size.width > 100)
                        {
                            const int inset_w = bounds.size.width / 4;
                            bounds.origin.x += inset_w;
                            bounds.size.width -= 2*inset_w;
                        }
                    }
                    
                    if (num_lines + 2 < static_cast<size_t>(bounds.size.height))
                    {
                        bounds.origin.y += (bounds.size.height - num_lines + 2)/2;
                        bounds.size.height = num_lines + 2;
                    }
                    else
                    {
                        if (bounds.size.height > 100)
                        {
                            const int inset_h = bounds.size.height / 4;
                            bounds.origin.y += inset_h;
                            bounds.size.height -= 2*inset_h;
                        }
                    }
                    WindowSP help_window_sp;
                    Window *parent_window = GetParent();
                    if (parent_window)
                        help_window_sp = parent_window->CreateSubWindow("Help", bounds, true);
                    else
                        help_window_sp = CreateSubWindow("Help", bounds, true);
                    help_window_sp->SetDelegate(WindowDelegateSP(help_delegate_ap.release()));
                    return true;
                }
            }
            return false;
        }

        virtual HandleCharResult
        HandleChar (int key)
        {
            // Always check the active window first
            HandleCharResult result = eKeyNotHandled;
            WindowSP active_window_sp = GetActiveWindow ();
            if (active_window_sp)
            {
                result = active_window_sp->HandleChar (key);
                if (result != eKeyNotHandled)
                    return result;
            }
            
            if (m_delegate_sp)
            {
                result = m_delegate_sp->WindowDelegateHandleChar (*this, key);
                if (result != eKeyNotHandled)
                    return result;
            }

            // Then check for any windows that want any keys
            // that weren't handled. This is typically only
            // for a menubar.
            // Make a copy of the subwindows in case any HandleChar()
            // functions muck with the subwindows. If we don't do this,
            // we can crash when iterating over the subwindows.
            Windows subwindows (m_subwindows);
            for (auto subwindow_sp : subwindows)
            {
                if (subwindow_sp->m_can_activate == false)
                {
                    HandleCharResult result = subwindow_sp->HandleChar(key);
                    if (result != eKeyNotHandled)
                        return result;
                }
            }

            return eKeyNotHandled;
        }

        bool
        SetActiveWindow (Window *window)
        {
            const size_t num_subwindows = m_subwindows.size();
            for (size_t i=0; i<num_subwindows; ++i)
            {
                if (m_subwindows[i].get() == window)
                {
                    m_prev_active_window_idx = m_curr_active_window_idx;
                    ::top_panel (window->m_panel);
                    m_curr_active_window_idx = i;
                    return true;
                }
            }
            return false;
        }

        WindowSP
        GetActiveWindow ()
        {
            if (!m_subwindows.empty())
            {
                if (m_curr_active_window_idx >= m_subwindows.size())
                {
                    if (m_prev_active_window_idx < m_subwindows.size())
                    {
                        m_curr_active_window_idx = m_prev_active_window_idx;
                        m_prev_active_window_idx = UINT32_MAX;
                    }
                    else if (IsActive())
                    {
                        m_prev_active_window_idx = UINT32_MAX;
                        m_curr_active_window_idx = UINT32_MAX;
                        
                        // Find first window that wants to be active if this window is active
                        const size_t num_subwindows = m_subwindows.size();
                        for (size_t i=0; i<num_subwindows; ++i)
                        {
                            if (m_subwindows[i]->GetCanBeActive())
                            {
                                m_curr_active_window_idx = i;
                                break;
                            }
                        }
                    }
                }
                
                if (m_curr_active_window_idx < m_subwindows.size())
                    return m_subwindows[m_curr_active_window_idx];
            }
            return WindowSP();
        }
        
        bool
        GetCanBeActive () const
        {
            return m_can_activate;
        }

        void
        SetCanBeActive (bool b)
        {
            m_can_activate = b;
        }
        
        const WindowDelegateSP &
        GetDelegate () const
        {
            return m_delegate_sp;
        }

        void
        SetDelegate (const WindowDelegateSP &delegate_sp)
        {
            m_delegate_sp = delegate_sp;
        }
        
        Window *
        GetParent () const
        {
            return m_parent;
        }
        
        bool
        IsActive () const
        {
            if (m_parent)
                return m_parent->GetActiveWindow().get() == this;
            else
                return true; // Top level window is always active
        }
        
        void
        SelectNextWindowAsActive ()
        {
            // Move active focus to next window
            const size_t num_subwindows = m_subwindows.size();
            if (m_curr_active_window_idx == UINT32_MAX)
            {
                uint32_t idx = 0;
                for (auto subwindow_sp : m_subwindows)
                {
                    if (subwindow_sp->GetCanBeActive())
                    {
                        m_curr_active_window_idx = idx;
                        break;
                    }
                    ++idx;
                }
            }
            else if (m_curr_active_window_idx + 1 < num_subwindows)
            {
                bool handled = false;
                m_prev_active_window_idx = m_curr_active_window_idx;
                for (size_t idx=m_curr_active_window_idx + 1; idx<num_subwindows; ++idx)
                {
                    if (m_subwindows[idx]->GetCanBeActive())
                    {
                        m_curr_active_window_idx = idx;
                        handled = true;
                        break;
                    }
                }
                if (!handled)
                {
                    for (size_t idx=0; idx<=m_prev_active_window_idx; ++idx)
                    {
                        if (m_subwindows[idx]->GetCanBeActive())
                        {
                            m_curr_active_window_idx = idx;
                            break;
                        }
                    }
                }
            }
            else
            {
                m_prev_active_window_idx = m_curr_active_window_idx;
                for (size_t idx=0; idx<num_subwindows; ++idx)
                {
                    if (m_subwindows[idx]->GetCanBeActive())
                    {
                        m_curr_active_window_idx = idx;
                        break;
                    }
                }
            }
        }

        const char *
        GetName () const
        {
            return m_name.c_str();
        }

    protected:
        std::string m_name;
        WINDOW *m_window;
        PANEL *m_panel;
        Window *m_parent;
        Windows m_subwindows;
        WindowDelegateSP m_delegate_sp;
        uint32_t m_curr_active_window_idx;
        uint32_t m_prev_active_window_idx;
        bool m_delete;
        bool m_needs_update;
        bool m_can_activate;
        bool m_is_subwin;
        
    private:
        DISALLOW_COPY_AND_ASSIGN(Window);
    };
    
    class MenuDelegate
    {
    public:
        virtual ~MenuDelegate() = default;

        virtual MenuActionResult
        MenuDelegateAction (Menu &menu) = 0;
    };

    class Menu : public WindowDelegate
    {
    public:
        enum class Type
        {
            Invalid,
            Bar,
            Item,
            Separator
        };
        
        // Menubar or separator constructor
        Menu (Type type);
        
        // Menuitem constructor
        Menu (const char *name,
              const char *key_name,
              int key_value,
              uint64_t identifier);

        ~Menu() override = default;

        const MenuDelegateSP &
        GetDelegate () const
        {
            return m_delegate_sp;
        }
        
        void
        SetDelegate (const MenuDelegateSP &delegate_sp)
        {
            m_delegate_sp = delegate_sp;
        }
        
        void
        RecalculateNameLengths();

        void
        AddSubmenu (const MenuSP &menu_sp);
        
        int
        DrawAndRunMenu (Window &window);
        
        void
        DrawMenuTitle (Window &window, bool highlight);

        bool
        WindowDelegateDraw (Window &window, bool force) override;
        
        HandleCharResult
        WindowDelegateHandleChar (Window &window, int key) override;

        MenuActionResult
        ActionPrivate (Menu &menu)
        {
            MenuActionResult result = MenuActionResult::NotHandled;
            if (m_delegate_sp)
            {
                result = m_delegate_sp->MenuDelegateAction (menu);
                if (result != MenuActionResult::NotHandled)
                    return result;
            }
            else if (m_parent)
            {
                result = m_parent->ActionPrivate(menu);
                if (result != MenuActionResult::NotHandled)
                    return result;
            }
            return m_canned_result;
        }

        MenuActionResult
        Action ()
        {
            // Call the recursive action so it can try to handle it
            // with the menu delegate, and if not, try our parent menu
            return ActionPrivate (*this);
        }
        
        void
        SetCannedResult (MenuActionResult result)
        {
            m_canned_result = result;
        }

        Menus &
        GetSubmenus()
        {
            return m_submenus;
        }

        const Menus &
        GetSubmenus() const
        {
            return m_submenus;
        }

        int
        GetSelectedSubmenuIndex () const
        {
            return m_selected;
        }
        
        void
        SetSelectedSubmenuIndex (int idx)
        {
            m_selected = idx;
        }

        Type
        GetType () const
        {
            return m_type;
        }
        
        int
        GetStartingColumn() const
        {
            return m_start_col;
        }

        void
        SetStartingColumn(int col)
        {
            m_start_col = col;
        }

        int
        GetKeyValue() const
        {
            return m_key_value;
        }
        
        void
        SetKeyValue(int key_value)
        {
            m_key_value = key_value;
        }

        std::string &
        GetName()
        {
            return m_name;
        }

        std::string &
        GetKeyName()
        {
            return m_key_name;
        }

        int
        GetDrawWidth () const
        {
            return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
        }

        uint64_t
        GetIdentifier() const
        {
            return m_identifier;
        }

        void
        SetIdentifier (uint64_t identifier)
        {
            m_identifier = identifier;
        }

    protected:
        std::string m_name;
        std::string m_key_name;
        uint64_t m_identifier;
        Type m_type;
        int m_key_value;
        int m_start_col;
        int m_max_submenu_name_length;
        int m_max_submenu_key_name_length;
        int m_selected;
        Menu *m_parent;
        Menus m_submenus;
        WindowSP m_menu_window_sp;
        MenuActionResult m_canned_result;
        MenuDelegateSP m_delegate_sp;
    };

    // Menubar or separator constructor
    Menu::Menu (Type type) :
        m_name (),
        m_key_name (),
        m_identifier (0),
        m_type (type),
        m_key_value (0),
        m_start_col (0),
        m_max_submenu_name_length (0),
        m_max_submenu_key_name_length (0),
        m_selected (0),
        m_parent (NULL),
        m_submenus (),
        m_canned_result (MenuActionResult::NotHandled),
        m_delegate_sp()
    {
    }

    // Menuitem constructor
    Menu::Menu (const char *name,
                const char *key_name,
                int key_value,
                uint64_t identifier) :
        m_name (),
        m_key_name (),
        m_identifier (identifier),
        m_type (Type::Invalid),
        m_key_value (key_value),
        m_start_col (0),
        m_max_submenu_name_length (0),
        m_max_submenu_key_name_length (0),
        m_selected (0),
        m_parent (NULL),
        m_submenus (),
        m_canned_result (MenuActionResult::NotHandled),
        m_delegate_sp()
    {
        if (name && name[0])
        {
            m_name = name;
            m_type = Type::Item;
            if (key_name && key_name[0])
                m_key_name = key_name;
        }
        else
        {
            m_type = Type::Separator;
        }
    }

    void
    Menu::RecalculateNameLengths()
    {
        m_max_submenu_name_length = 0;
        m_max_submenu_key_name_length = 0;
        Menus &submenus = GetSubmenus();
        const size_t num_submenus = submenus.size();
        for (size_t i=0; i<num_submenus; ++i)
        {
            Menu *submenu = submenus[i].get();
            if (static_cast<size_t>(m_max_submenu_name_length) < submenu->m_name.size())
                m_max_submenu_name_length = submenu->m_name.size();
            if (static_cast<size_t>(m_max_submenu_key_name_length) < submenu->m_key_name.size())
                m_max_submenu_key_name_length = submenu->m_key_name.size();
        }
    }

    void
    Menu::AddSubmenu (const MenuSP &menu_sp)
    {
        menu_sp->m_parent = this;
        if (static_cast<size_t>(m_max_submenu_name_length) < menu_sp->m_name.size())
            m_max_submenu_name_length = menu_sp->m_name.size();
        if (static_cast<size_t>(m_max_submenu_key_name_length) < menu_sp->m_key_name.size())
            m_max_submenu_key_name_length = menu_sp->m_key_name.size();
        m_submenus.push_back(menu_sp);
    }

    void
    Menu::DrawMenuTitle (Window &window, bool highlight)
    {
        if (m_type == Type::Separator)
        {
            window.MoveCursor(0, window.GetCursorY());
            window.PutChar(ACS_LTEE);
            int width = window.GetWidth();
            if (width > 2)
            {
                width -= 2;
                for (int i=0; i< width; ++i)
                    window.PutChar(ACS_HLINE);
            }
            window.PutChar(ACS_RTEE);
        }
        else
        {
            const int shortcut_key = m_key_value;
            bool underlined_shortcut = false;
            const attr_t hilgight_attr = A_REVERSE;
            if (highlight)
                window.AttributeOn(hilgight_attr);
            if (isprint(shortcut_key))
            {
                size_t lower_pos = m_name.find(tolower(shortcut_key));
                size_t upper_pos = m_name.find(toupper(shortcut_key));
                const char *name = m_name.c_str();
                size_t pos = std::min<size_t>(lower_pos, upper_pos);
                if (pos != std::string::npos)
                {
                    underlined_shortcut = true;
                    if (pos > 0)
                    {
                        window.PutCString(name, pos);
                        name += pos;
                    }
                    const attr_t shortcut_attr = A_UNDERLINE|A_BOLD;
                    window.AttributeOn (shortcut_attr);
                    window.PutChar(name[0]);
                    window.AttributeOff(shortcut_attr);
                    name++;
                    if (name[0])
                        window.PutCString(name);
                }
            }
            
            if (!underlined_shortcut)
            {
                window.PutCString(m_name.c_str());
            }

            if (highlight)
                window.AttributeOff(hilgight_attr);

            if (m_key_name.empty())
            {
                if (!underlined_shortcut && isprint(m_key_value))
                {
                    window.AttributeOn (COLOR_PAIR(3));
                    window.Printf (" (%c)", m_key_value);
                    window.AttributeOff (COLOR_PAIR(3));
                }
            }
            else
            {
                window.AttributeOn (COLOR_PAIR(3));
                window.Printf (" (%s)", m_key_name.c_str());
                window.AttributeOff (COLOR_PAIR(3));
            }
        }
    }
    
    bool
    Menu::WindowDelegateDraw (Window &window, bool force)
    {
        Menus &submenus = GetSubmenus();
        const size_t num_submenus = submenus.size();
        const int selected_idx = GetSelectedSubmenuIndex();
        Menu::Type menu_type = GetType ();
        switch (menu_type)
        {
        case  Menu::Type::Bar:
            {
                window.SetBackground(2);
                window.MoveCursor(0, 0);
                for (size_t i=0; i<num_submenus; ++i)
                {
                    Menu *menu = submenus[i].get();
                    if (i > 0)
                        window.PutChar(' ');
                    menu->SetStartingColumn (window.GetCursorX());
                    window.PutCString("| ");
                    menu->DrawMenuTitle (window, false);
                }
                window.PutCString(" |");
                window.DeferredRefresh();
            }
            break;
                
        case Menu::Type::Item:
            {
                int y = 1;
                int x = 3;
                // Draw the menu
                int cursor_x = 0;
                int cursor_y = 0;
                window.Erase();
                window.SetBackground(2);
                window.Box();
                for (size_t i=0; i<num_submenus; ++i)
                {
                    const bool is_selected =
                      (i == static_cast<size_t>(selected_idx));
                    window.MoveCursor(x, y + i);
                    if (is_selected)
                    {
                        // Remember where we want the cursor to be
                        cursor_x = x-1;
                        cursor_y = y+i;
                    }
                    submenus[i]->DrawMenuTitle (window, is_selected);
                }
                window.MoveCursor(cursor_x, cursor_y);
                window.DeferredRefresh();
            }
            break;

        default:
        case Menu::Type::Separator:
            break;
        }
        return true; // Drawing handled...
    }
    
    HandleCharResult
    Menu::WindowDelegateHandleChar (Window &window, int key)
    {
        HandleCharResult result = eKeyNotHandled;
        
        Menus &submenus = GetSubmenus();
        const size_t num_submenus = submenus.size();
        const int selected_idx = GetSelectedSubmenuIndex();
        Menu::Type menu_type = GetType ();
        if (menu_type == Menu::Type::Bar)
        {
            MenuSP run_menu_sp;
            switch (key)
            {
                case KEY_DOWN:
                case KEY_UP:
                    // Show last menu or first menu
                    if (selected_idx < static_cast<int>(num_submenus))
                        run_menu_sp = submenus[selected_idx];
                    else if (!submenus.empty())
                        run_menu_sp = submenus.front();
                    result = eKeyHandled;
                    break;
                    
                case KEY_RIGHT:
                {
                    ++m_selected;
                    if (m_selected >= static_cast<int>(num_submenus))
                        m_selected = 0;
                    if (m_selected < static_cast<int>(num_submenus))
                        run_menu_sp = submenus[m_selected];
                    else if (!submenus.empty())
                        run_menu_sp = submenus.front();
                    result = eKeyHandled;
                }
                    break;
                    
                case KEY_LEFT:
                {
                    --m_selected;
                    if (m_selected < 0)
                        m_selected = num_submenus - 1;
                    if (m_selected < static_cast<int>(num_submenus))
                        run_menu_sp = submenus[m_selected];
                    else if (!submenus.empty())
                        run_menu_sp = submenus.front();
                    result = eKeyHandled;
                }
                    break;
                    
                default:
                    for (size_t i=0; i<num_submenus; ++i)
                    {
                        if (submenus[i]->GetKeyValue() == key)
                        {
                            SetSelectedSubmenuIndex(i);
                            run_menu_sp = submenus[i];
                            result = eKeyHandled;
                            break;
                        }
                    }
                    break;
            }
            
            if (run_menu_sp)
            {
                // Run the action on this menu in case we need to populate the
                // menu with dynamic content and also in case check marks, and
                // any other menu decorations need to be calculated
                if (run_menu_sp->Action() == MenuActionResult::Quit)
                    return eQuitApplication;

                Rect menu_bounds;
                menu_bounds.origin.x = run_menu_sp->GetStartingColumn();
                menu_bounds.origin.y = 1;
                menu_bounds.size.width = run_menu_sp->GetDrawWidth();
                menu_bounds.size.height = run_menu_sp->GetSubmenus().size() + 2;
                if (m_menu_window_sp)
                    window.GetParent()->RemoveSubWindow(m_menu_window_sp.get());
                
                m_menu_window_sp = window.GetParent()->CreateSubWindow (run_menu_sp->GetName().c_str(),
                                                                        menu_bounds,
                                                                        true);
                m_menu_window_sp->SetDelegate (run_menu_sp);
            }
        }
        else if (menu_type == Menu::Type::Item)
        {
            switch (key)
            {
                case KEY_DOWN:
                    if (m_submenus.size() > 1)
                    {
                        const int start_select = m_selected;
                        while (++m_selected != start_select)
                        {
                            if (static_cast<size_t>(m_selected) >= num_submenus)
                                m_selected = 0;
                            if (m_submenus[m_selected]->GetType() == Type::Separator)
                                continue;
                            else
                                break;
                        }
                        return eKeyHandled;
                    }
                    break;
                    
                case KEY_UP:
                    if (m_submenus.size() > 1)
                    {
                        const int start_select = m_selected;
                        while (--m_selected != start_select)
                        {
                            if (m_selected < static_cast<int>(0))
                                m_selected = num_submenus - 1;
                            if (m_submenus[m_selected]->GetType() == Type::Separator)
                                continue;
                            else
                                break;
                        }
                        return eKeyHandled;
                    }
                    break;
                    
                case KEY_RETURN:
                    if (static_cast<size_t>(selected_idx) < num_submenus)
                    {
                        if (submenus[selected_idx]->Action() == MenuActionResult::Quit)
                            return eQuitApplication;
                        window.GetParent()->RemoveSubWindow(&window);
                        return eKeyHandled;
                    }
                    break;
                    
                case KEY_ESCAPE: // Beware: pressing escape key has 1 to 2 second delay in case other chars are entered for escaped sequences
                    window.GetParent()->RemoveSubWindow(&window);
                    return eKeyHandled;
                    
                default:
                {
                    for (size_t i=0; i<num_submenus; ++i)
                    {
                        Menu *menu = submenus[i].get();
                        if (menu->GetKeyValue() == key)
                        {
                            SetSelectedSubmenuIndex(i);
                            window.GetParent()->RemoveSubWindow(&window);
                            if (menu->Action() == MenuActionResult::Quit)
                                return eQuitApplication;
                            return eKeyHandled;
                        }
                    }
                }
                    break;
                    
            }
        }
        else if (menu_type == Menu::Type::Separator)
        {
        }
        return result;
    }

    class Application
    {
    public:
        Application (FILE *in, FILE *out) :
            m_window_sp(),
            m_screen (NULL),
            m_in (in),
            m_out (out)
        {
            
        }
        
        ~Application ()
        {
            m_window_delegates.clear();
            m_window_sp.reset();
            if (m_screen)
            {
                ::delscreen(m_screen);
                m_screen = NULL;
            }
        }
        
        void
        Initialize ()
        {
            ::setlocale(LC_ALL, "");
            ::setlocale(LC_CTYPE, "");
#if 0
            ::initscr();
#else
            m_screen = ::newterm(NULL, m_out, m_in);
#endif
            ::start_color();
            ::curs_set(0);
            ::noecho();
            ::keypad(stdscr,TRUE);
        }
        
        void
        Terminate ()
        {
            ::endwin();
        }
        
        void
        Run (Debugger &debugger)
        {
            bool done = false;
            int delay_in_tenths_of_a_second = 1;
            
            // Alas the threading model in curses is a bit lame so we need to
            // resort to polling every 0.5 seconds. We could poll for stdin
            // ourselves and then pass the keys down but then we need to
            // translate all of the escape sequences ourselves. So we resort to
            // polling for input because we need to receive async process events
            // while in this loop.
            
            halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths of seconds seconds when calling Window::GetChar()

            ListenerSP listener_sp (new Listener ("lldb.IOHandler.curses.Application"));
            ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
            ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
            ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
            debugger.EnableForwardEvents (listener_sp);

            bool update = true;
#if defined(__APPLE__)
            std::deque<int> escape_chars;
#endif
            
            while (!done)
            {
                if (update)
                {
                    m_window_sp->Draw(false);
                    // All windows should be calling Window::DeferredRefresh() instead
                    // of Window::Refresh() so we can do a single update and avoid
                    // any screen blinking
                    update_panels();

                    // Cursor hiding isn't working on MacOSX, so hide it in the top left corner
                    m_window_sp->MoveCursor(0, 0);

                    doupdate();
                    update = false;
                }
                
#if defined(__APPLE__)
                // Terminal.app doesn't map its function keys correctly, F1-F4 default to:
                // \033OP, \033OQ, \033OR, \033OS, so lets take care of this here if possible
                int ch;
                if (escape_chars.empty())
                    ch = m_window_sp->GetChar();
                else
                {
                    ch = escape_chars.front();
                    escape_chars.pop_front();
                }
                if (ch == KEY_ESCAPE)
                {
                    int ch2 = m_window_sp->GetChar();
                    if (ch2 == 'O')
                    {
                        int ch3 = m_window_sp->GetChar();
                        switch (ch3)
                        {
                            case 'P': ch = KEY_F(1); break;
                            case 'Q': ch = KEY_F(2); break;
                            case 'R': ch = KEY_F(3); break;
                            case 'S': ch = KEY_F(4); break;
                            default:
                                escape_chars.push_back(ch2);
                                if (ch3 != -1)
                                    escape_chars.push_back(ch3);
                                break;
                        }
                    }
                    else if (ch2 != -1)
                        escape_chars.push_back(ch2);
                }
#else
                int ch = m_window_sp->GetChar();

#endif
                if (ch == -1)
                {
                    if (feof(m_in) || ferror(m_in))
                    {
                        done = true;
                    }
                    else
                    {
                        // Just a timeout from using halfdelay(), check for events
                        EventSP event_sp;
                        while (listener_sp->PeekAtNextEvent())
                        {
                            listener_sp->GetNextEvent(event_sp);
                            
                            if (event_sp)
                            {
                                Broadcaster *broadcaster = event_sp->GetBroadcaster();
                                if (broadcaster)
                                {
                                    //uint32_t event_type = event_sp->GetType();
                                    ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
                                    if (broadcaster_class == broadcaster_class_process)
                                    {
                                        debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
                                        update = true;
                                        continue; // Don't get any key, just update our view
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    HandleCharResult key_result = m_window_sp->HandleChar(ch);
                    switch (key_result)
                    {
                        case eKeyHandled:
                            debugger.GetCommandInterpreter().UpdateExecutionContext(NULL);
                            update = true;
                            break;
                        case eKeyNotHandled:
                            break;
                        case eQuitApplication:
                            done = true;
                            break;
                    }
                }
            }
            
            debugger.CancelForwardEvents (listener_sp);
        }
        
        WindowSP &
        GetMainWindow ()
        {
            if (!m_window_sp)
                m_window_sp.reset (new Window ("main", stdscr, false));
            return m_window_sp;
        }
        
        WindowDelegates &
        GetWindowDelegates ()
        {
            return m_window_delegates;
        }

    protected:
        WindowSP m_window_sp;
        WindowDelegates m_window_delegates;
        SCREEN *m_screen;
        FILE *m_in;
        FILE *m_out;
    };

} // namespace curses

using namespace curses;

struct Row
{
    ValueObjectSP valobj;
    Row *parent;
    int row_idx;
    int x;
    int y;
    bool might_have_children;
    bool expanded;
    bool calculated_children;
    std::vector<Row> children;
    
    Row (const ValueObjectSP &v, Row *p) :
    valobj (v),
    parent (p),
    row_idx(0),
    x(1),
    y(1),
    might_have_children (v ? v->MightHaveChildren() : false),
    expanded (false),
    calculated_children (false),
    children()
    {
    }
    
    size_t
    GetDepth () const
    {
        if (parent)
            return 1 + parent->GetDepth();
        return 0;
    }
    
    void
    Expand()
    {
        expanded = true;
        if (!calculated_children)
        {
            calculated_children = true;
            if (valobj)
            {
                const size_t num_children = valobj->GetNumChildren();
                for (size_t i=0; i<num_children; ++i)
                {
                    children.push_back(Row (valobj->GetChildAtIndex(i, true), this));
                }
            }
        }
    }
    
    void
    Unexpand ()
    {
        expanded = false;
    }
    
    void
    DrawTree (Window &window)
    {
        if (parent)
            parent->DrawTreeForChild (window, this, 0);
        
        if (might_have_children)
        {
            // It we can get UTF8 characters to work we should try to use the "symbol"
            // UTF8 string below
//            const char *symbol = "";
//            if (row.expanded)
//                symbol = "\xe2\x96\xbd ";
//            else
//                symbol = "\xe2\x96\xb7 ";
//            window.PutCString (symbol);
            
            // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
            // 'v' or '>' character...
//            if (expanded)
//                window.PutChar (ACS_DARROW);
//            else
//                window.PutChar (ACS_RARROW);
            // Since we can't find any good looking right arrow/down arrow
            // symbols, just use a diamond...
            window.PutChar (ACS_DIAMOND);
            window.PutChar (ACS_HLINE);
        }
    }

    void
    DrawTreeForChild (Window &window, Row *child, uint32_t reverse_depth)
    {
        if (parent)
            parent->DrawTreeForChild (window, this, reverse_depth + 1);
        
        if (&children.back() == child)
        {
            // Last child
            if (reverse_depth == 0)
            {
                window.PutChar (ACS_LLCORNER);
                window.PutChar (ACS_HLINE);
            }
            else
            {
                window.PutChar (' ');
                window.PutChar (' ');
            }
        }
        else
        {
            if (reverse_depth == 0)
            {
                window.PutChar (ACS_LTEE);
                window.PutChar (ACS_HLINE);
            }
            else
            {
                window.PutChar (ACS_VLINE);
                window.PutChar (' ');
            }
        }
    }
};

struct DisplayOptions
{
    bool show_types;
};

class TreeItem;

class TreeDelegate
{
public:
    TreeDelegate() {}
    virtual ~TreeDelegate() = default;

    virtual void TreeDelegateDrawTreeItem (TreeItem &item, Window &window) = 0;
    virtual void TreeDelegateGenerateChildren (TreeItem &item) = 0;
    virtual bool TreeDelegateItemSelected (TreeItem &item) = 0; // Return true if we need to update views
};

typedef std::shared_ptr<TreeDelegate> TreeDelegateSP;

class TreeItem
{
public:
    
    TreeItem (TreeItem *parent, TreeDelegate &delegate, bool might_have_children) :
        m_parent (parent),
        m_delegate (delegate),
        m_user_data (NULL),
        m_identifier (0),
        m_row_idx (-1),
        m_children (),
        m_might_have_children (might_have_children),
        m_is_expanded (false)
    {
    }

    TreeItem &
    operator=(const TreeItem &rhs)
    {
        if (this != &rhs)
        {
            m_parent = rhs.m_parent;
            m_delegate = rhs.m_delegate;
            m_user_data = rhs.m_user_data;
            m_identifier = rhs.m_identifier;
            m_row_idx = rhs.m_row_idx;
            m_children = rhs.m_children;
            m_might_have_children = rhs.m_might_have_children;
            m_is_expanded = rhs.m_is_expanded;
        }
        return *this;
    }

    size_t
    GetDepth () const
    {
        if (m_parent)
            return 1 + m_parent->GetDepth();
        return 0;
    }
    
    int
    GetRowIndex () const
    {
        return m_row_idx;
    }

    void
    ClearChildren ()
    {
        m_children.clear();
    }

    void
    Resize (size_t n, const TreeItem &t)
    {
        m_children.resize(n, t);
    }
    
    TreeItem &
    operator [](size_t i)
    {
        return m_children[i];
    }

    void
    SetRowIndex (int row_idx)
    {
        m_row_idx = row_idx;
    }

    size_t
    GetNumChildren ()
    {
        m_delegate.TreeDelegateGenerateChildren (*this);
        return m_children.size();
    }

    void
    ItemWasSelected ()
    {
        m_delegate.TreeDelegateItemSelected(*this);
    }

    void
    CalculateRowIndexes (int &row_idx)
    {
        SetRowIndex(row_idx);
        ++row_idx;

        const bool expanded = IsExpanded();

        // The root item must calculate its children,
        // or we must calculate the number of children
        // if the item is expanded
        if (m_parent == NULL || expanded)
            GetNumChildren();
        
        for (auto &item : m_children)
        {
            if (expanded)
                item.CalculateRowIndexes(row_idx);
            else
                item.SetRowIndex(-1);
        }
    }

    TreeItem *
    GetParent ()
    {
        return m_parent;
    }

    bool
    IsExpanded () const
    {
        return m_is_expanded;
    }

    void
    Expand()
    {
        m_is_expanded = true;
    }
    
    void
    Unexpand ()
    {
        m_is_expanded = false;
    }
    
    bool
    Draw (Window &window,
          const int first_visible_row,
          const uint32_t selected_row_idx,
          int &row_idx,
          int &num_rows_left)
    {
        if (num_rows_left <= 0)
            return false;

        if (m_row_idx >= first_visible_row)
        {
            window.MoveCursor(2, row_idx + 1);

            if (m_parent)
                m_parent->DrawTreeForChild (window, this, 0);
        
            if (m_might_have_children)
            {
                // It we can get UTF8 characters to work we should try to use the "symbol"
                // UTF8 string below
                //            const char *symbol = "";
                //            if (row.expanded)
                //                symbol = "\xe2\x96\xbd ";
                //            else
                //                symbol = "\xe2\x96\xb7 ";
                //            window.PutCString (symbol);
                
                // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
                // 'v' or '>' character...
                //            if (expanded)
                //                window.PutChar (ACS_DARROW);
                //            else
                //                window.PutChar (ACS_RARROW);
                // Since we can't find any good looking right arrow/down arrow
                // symbols, just use a diamond...
                window.PutChar (ACS_DIAMOND);
                window.PutChar (ACS_HLINE);
            }
            bool highlight =
              (selected_row_idx == static_cast<size_t>(m_row_idx)) && window.IsActive();

            if (highlight)
                window.AttributeOn(A_REVERSE);

            m_delegate.TreeDelegateDrawTreeItem(*this, window);

            if (highlight)
                window.AttributeOff(A_REVERSE);
            ++row_idx;
            --num_rows_left;
        }

        if (num_rows_left <= 0)
            return false; // We are done drawing...

        if (IsExpanded())
        {
            for (auto &item : m_children)
            {
                // If we displayed all the rows and item.Draw() returns
                // false we are done drawing and can exit this for loop
                if (item.Draw(window, first_visible_row, selected_row_idx, row_idx, num_rows_left) == false)
                    break;
            }
        }
        return num_rows_left >= 0; // Return true if not done drawing yet
    }
    
    void
    DrawTreeForChild (Window &window, TreeItem *child, uint32_t reverse_depth)
    {
        if (m_parent)
            m_parent->DrawTreeForChild (window, this, reverse_depth + 1);
        
        if (&m_children.back() == child)
        {
            // Last child
            if (reverse_depth == 0)
            {
                window.PutChar (ACS_LLCORNER);
                window.PutChar (ACS_HLINE);
            }
            else
            {
                window.PutChar (' ');
                window.PutChar (' ');
            }
        }
        else
        {
            if (reverse_depth == 0)
            {
                window.PutChar (ACS_LTEE);
                window.PutChar (ACS_HLINE);
            }
            else
            {
                window.PutChar (ACS_VLINE);
                window.PutChar (' ');
            }
        }
    }
    
    TreeItem *
    GetItemForRowIndex (uint32_t row_idx)
    {
        if (static_cast<uint32_t>(m_row_idx) == row_idx)
            return this;
        if (m_children.empty())
            return NULL;
        if (IsExpanded())
        {
            for (auto &item : m_children)
            {
                TreeItem *selected_item_ptr = item.GetItemForRowIndex(row_idx);
                if (selected_item_ptr)
                    return selected_item_ptr;
            }
        }
        return NULL;
    }
    
    void *
    GetUserData() const
    {
        return m_user_data;
    }
    
    void
    SetUserData (void *user_data)
    {
        m_user_data = user_data;
    }

    uint64_t
    GetIdentifier() const
    {
        return m_identifier;
    }
    
    void
    SetIdentifier (uint64_t identifier)
    {
        m_identifier = identifier;
    }

    void
    SetMightHaveChildren (bool b)
    {
        m_might_have_children = b;
    }

protected:
    TreeItem *m_parent;
    TreeDelegate &m_delegate;
    void *m_user_data;
    uint64_t m_identifier;
    int m_row_idx; // Zero based visible row index, -1 if not visible or for the root item
    std::vector<TreeItem> m_children;
    bool m_might_have_children;
    bool m_is_expanded;
};

class TreeWindowDelegate : public WindowDelegate
{
public:
    TreeWindowDelegate (Debugger &debugger, const TreeDelegateSP &delegate_sp) :
        m_debugger (debugger),
        m_delegate_sp (delegate_sp),
        m_root (NULL, *delegate_sp, true),
        m_selected_item (NULL),
        m_num_rows (0),
        m_selected_row_idx (0),
        m_first_visible_row (0),
        m_min_x (0),
        m_min_y (0),
        m_max_x (0),
        m_max_y (0)
    {
    }
    
    int
    NumVisibleRows () const
    {
        return m_max_y - m_min_y;
    }

    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
        Process *process = exe_ctx.GetProcessPtr();
        
        bool display_content = false;
        if (process)
        {
            StateType state = process->GetState();
            if (StateIsStoppedState(state, true))
            {
                // We are stopped, so it is ok to
                display_content = true;
            }
            else if (StateIsRunningState(state))
            {
                return true; // Don't do any updating when we are running
            }
        }

        m_min_x = 2;
        m_min_y = 1;
        m_max_x = window.GetWidth() - 1;
        m_max_y = window.GetHeight() - 1;
        
        window.Erase();
        window.DrawTitleBox (window.GetName());

        if (display_content)
        {
            const int num_visible_rows = NumVisibleRows();
            m_num_rows = 0;
            m_root.CalculateRowIndexes(m_num_rows);
            
            // If we unexpanded while having something selected our
            // total number of rows is less than the num visible rows,
            // then make sure we show all the rows by setting the first
            // visible row accordingly.
            if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
                m_first_visible_row = 0;
            
            // Make sure the selected row is always visible
            if (m_selected_row_idx < m_first_visible_row)
                m_first_visible_row = m_selected_row_idx;
            else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
                m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
            
            int row_idx = 0;
            int num_rows_left = num_visible_rows;
            m_root.Draw (window, m_first_visible_row, m_selected_row_idx, row_idx, num_rows_left);
            // Get the selected row
            m_selected_item = m_root.GetItemForRowIndex (m_selected_row_idx);
        }
        else
        {
            m_selected_item = NULL;
        }
        
        window.DeferredRefresh();
        
        
        return true; // Drawing handled
    }

    const char *
    WindowDelegateGetHelpText () override
    {
        return "Thread window keyboard shortcuts:";
    }
    
    KeyHelp *
    WindowDelegateGetKeyHelp () override
    {
        static curses::KeyHelp g_source_view_key_help[] = {
            { KEY_UP, "Select previous item" },
            { KEY_DOWN, "Select next item" },
            { KEY_RIGHT, "Expand the selected item" },
            { KEY_LEFT, "Unexpand the selected item or select parent if not expanded" },
            { KEY_PPAGE, "Page up" },
            { KEY_NPAGE, "Page down" },
            { 'h', "Show help dialog" },
            { ' ', "Toggle item expansion" },
            { ',', "Page up" },
            { '.', "Page down" },
            { '\0', NULL }
        };
        return g_source_view_key_help;
    }
    
    HandleCharResult
    WindowDelegateHandleChar (Window &window, int c) override
    {
        switch(c)
        {
            case ',':
            case KEY_PPAGE:
                // Page up key
                if (m_first_visible_row > 0)
                {
                    if (m_first_visible_row > m_max_y)
                        m_first_visible_row -= m_max_y;
                    else
                        m_first_visible_row = 0;
                    m_selected_row_idx = m_first_visible_row;
                    m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
                    if (m_selected_item)
                        m_selected_item->ItemWasSelected ();
                }
                return eKeyHandled;
                
            case '.':
            case KEY_NPAGE:
                // Page down key
                if (m_num_rows > m_max_y)
                {
                    if (m_first_visible_row + m_max_y < m_num_rows)
                    {
                        m_first_visible_row += m_max_y;
                        m_selected_row_idx = m_first_visible_row;
                        m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
                        if (m_selected_item)
                            m_selected_item->ItemWasSelected ();
                    }
                }
                return eKeyHandled;
                
            case KEY_UP:
                if (m_selected_row_idx > 0)
                {
                    --m_selected_row_idx;
                    m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
                    if (m_selected_item)
                        m_selected_item->ItemWasSelected ();
                }
                return eKeyHandled;

            case KEY_DOWN:
                if (m_selected_row_idx + 1 < m_num_rows)
                {
                    ++m_selected_row_idx;
                    m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
                    if (m_selected_item)
                        m_selected_item->ItemWasSelected ();
                }
                return eKeyHandled;
                
            case KEY_RIGHT:
                if (m_selected_item)
                {
                    if (!m_selected_item->IsExpanded())
                        m_selected_item->Expand();
                }
                return eKeyHandled;
                
            case KEY_LEFT:
                if (m_selected_item)
                {
                    if (m_selected_item->IsExpanded())
                        m_selected_item->Unexpand();
                    else if (m_selected_item->GetParent())
                    {
                        m_selected_row_idx = m_selected_item->GetParent()->GetRowIndex();
                        m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
                        if (m_selected_item)
                            m_selected_item->ItemWasSelected ();
                    }
                }
                return eKeyHandled;
                
            case ' ':
                // Toggle expansion state when SPACE is pressed
                if (m_selected_item)
                {
                    if (m_selected_item->IsExpanded())
                        m_selected_item->Unexpand();
                    else
                        m_selected_item->Expand();
                }
                return eKeyHandled;
                
            case 'h':
                window.CreateHelpSubwindow ();
                return eKeyHandled;
                
            default:
                break;
        }
        return eKeyNotHandled;
    }

protected:
    Debugger &m_debugger;
    TreeDelegateSP m_delegate_sp;
    TreeItem m_root;
    TreeItem *m_selected_item;
    int m_num_rows;
    int m_selected_row_idx;
    int m_first_visible_row;
    int m_min_x;
    int m_min_y;
    int m_max_x;
    int m_max_y;
};

class FrameTreeDelegate : public TreeDelegate
{
public:
    FrameTreeDelegate () :
        TreeDelegate()
    {
        FormatEntity::Parse ("frame #${frame.index}: {${function.name}${function.pc-offset}}}",
                             m_format);
    }

    ~FrameTreeDelegate() override = default;

    void
    TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
    {
        Thread* thread = (Thread*)item.GetUserData();
        if (thread)
        {
            const uint64_t frame_idx = item.GetIdentifier();
            StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_idx);
            if (frame_sp)
            {
                StreamString strm;
                const SymbolContext &sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
                ExecutionContext exe_ctx (frame_sp);
                if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, NULL, NULL, false, false))
                {
                    int right_pad = 1;
                    window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
                }
            }
        }
    }

    void
    TreeDelegateGenerateChildren (TreeItem &item)  override
    {
        // No children for frames yet...
    }
    
    bool
    TreeDelegateItemSelected (TreeItem &item) override
    {
        Thread* thread = (Thread*)item.GetUserData();
        if (thread)
        {
            thread->GetProcess()->GetThreadList().SetSelectedThreadByID(thread->GetID());
            const uint64_t frame_idx = item.GetIdentifier();
            thread->SetSelectedFrameByIndex(frame_idx);
            return true;
        }
        return false;
    }

protected:
    FormatEntity::Entry m_format;
};

class ThreadTreeDelegate : public TreeDelegate
{
public:
    ThreadTreeDelegate (Debugger &debugger) :
        TreeDelegate(),
        m_debugger (debugger),
        m_tid (LLDB_INVALID_THREAD_ID),
        m_stop_id (UINT32_MAX)
    {
        FormatEntity::Parse ("thread #${thread.index}: tid = ${thread.id}{, stop reason = ${thread.stop-reason}}",
                             m_format);
    }

    ~ThreadTreeDelegate() override = default;

    ProcessSP
    GetProcess ()
    {
        return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
    }

    ThreadSP
    GetThread (const TreeItem &item)
    {
        ProcessSP process_sp = GetProcess ();
        if (process_sp)
            return process_sp->GetThreadList().FindThreadByID(item.GetIdentifier());
        return ThreadSP();
    }
    
    void
    TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
    {
        ThreadSP thread_sp = GetThread (item);
        if (thread_sp)
        {
            StreamString strm;
            ExecutionContext exe_ctx (thread_sp);
            if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
            {
                int right_pad = 1;
                window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
            }
        }
    }

    void
    TreeDelegateGenerateChildren (TreeItem &item) override
    {
        ProcessSP process_sp = GetProcess ();
        if (process_sp && process_sp->IsAlive())
        {
            StateType state = process_sp->GetState();
            if (StateIsStoppedState(state, true))
            {
                ThreadSP thread_sp = GetThread (item);
                if (thread_sp)
                {
                    if (m_stop_id == process_sp->GetStopID() && thread_sp->GetID() == m_tid)
                        return; // Children are already up to date
                    if (!m_frame_delegate_sp)
                    {
                        // Always expand the thread item the first time we show it
                        m_frame_delegate_sp.reset (new FrameTreeDelegate());
                    }

                    m_stop_id = process_sp->GetStopID();
                    m_tid = thread_sp->GetID();
                    
                    TreeItem t (&item, *m_frame_delegate_sp, false);
                    size_t num_frames = thread_sp->GetStackFrameCount();
                    item.Resize (num_frames, t);
                    for (size_t i=0; i<num_frames; ++i)
                    {
                        item[i].SetUserData(thread_sp.get());
                        item[i].SetIdentifier(i);
                    }
                }
                return;
            }
        }
        item.ClearChildren();
    }
    
    bool
    TreeDelegateItemSelected (TreeItem &item) override
    {
        ProcessSP process_sp = GetProcess ();
        if (process_sp && process_sp->IsAlive())
        {
            StateType state = process_sp->GetState();
            if (StateIsStoppedState(state, true))
            {
                ThreadSP thread_sp = GetThread (item);
                if (thread_sp)
                {
                    ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
                    Mutex::Locker locker (thread_list.GetMutex());
                    ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
                    if (selected_thread_sp->GetID() != thread_sp->GetID())
                    {
                        thread_list.SetSelectedThreadByID(thread_sp->GetID());
                        return true;
                    }
                }
            }
        }
        return false;
    }

protected:
    Debugger &m_debugger;
    std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp;
    lldb::user_id_t m_tid;
    uint32_t m_stop_id;
    FormatEntity::Entry m_format;
};

class ThreadsTreeDelegate : public TreeDelegate
{
public:
    ThreadsTreeDelegate (Debugger &debugger) :
        TreeDelegate(),
        m_thread_delegate_sp (),
        m_debugger (debugger),
        m_stop_id (UINT32_MAX)
    {
        FormatEntity::Parse("process ${process.id}{, name = ${process.name}}",
                            m_format);
    }

    ~ThreadsTreeDelegate() override = default;

    ProcessSP
    GetProcess ()
    {
        return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
    }

    void
    TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
    {
        ProcessSP process_sp = GetProcess ();
        if (process_sp && process_sp->IsAlive())
        {
            StreamString strm;
            ExecutionContext exe_ctx (process_sp);
            if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
            {
                int right_pad = 1;
                window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
            }
        }
    }

    void
    TreeDelegateGenerateChildren (TreeItem &item) override
    {
        ProcessSP process_sp = GetProcess ();
        if (process_sp && process_sp->IsAlive())
        {
            StateType state = process_sp->GetState();
            if (StateIsStoppedState(state, true))
            {
                const uint32_t stop_id = process_sp->GetStopID();
                if (m_stop_id == stop_id)
                    return; // Children are already up to date
                
                m_stop_id = stop_id;

                if (!m_thread_delegate_sp)
                {
                    // Always expand the thread item the first time we show it
                    //item.Expand();
                    m_thread_delegate_sp.reset (new ThreadTreeDelegate(m_debugger));
                }
                
                TreeItem t (&item, *m_thread_delegate_sp, false);
                ThreadList &threads = process_sp->GetThreadList();
                Mutex::Locker locker (threads.GetMutex());
                size_t num_threads = threads.GetSize();
                item.Resize (num_threads, t);
                for (size_t i=0; i<num_threads; ++i)
                {
                    item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID());
                    item[i].SetMightHaveChildren(true);
                }
                return;
            }
        }
        item.ClearChildren();
    }
    
    bool
    TreeDelegateItemSelected (TreeItem &item) override
    {
        return false;
    }
    
protected:
    std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
    Debugger &m_debugger;
    uint32_t m_stop_id;
    FormatEntity::Entry m_format;
};

class ValueObjectListDelegate : public WindowDelegate
{
public:
    ValueObjectListDelegate () :
        m_valobj_list (),
        m_rows (),
        m_selected_row (NULL),
        m_selected_row_idx (0),
        m_first_visible_row (0),
        m_num_rows (0),
        m_max_x (0),
        m_max_y (0)
    {
    }
    
    ValueObjectListDelegate (ValueObjectList &valobj_list) :
        m_valobj_list (valobj_list),
        m_rows (),
        m_selected_row (NULL),
        m_selected_row_idx (0),
        m_first_visible_row (0),
        m_num_rows (0),
        m_max_x (0),
        m_max_y (0)
    {
        SetValues (valobj_list);
    }

    ~ValueObjectListDelegate() override = default;

    void
    SetValues (ValueObjectList &valobj_list)
    {
        m_selected_row = NULL;
        m_selected_row_idx = 0;
        m_first_visible_row = 0;
        m_num_rows = 0;
        m_rows.clear();
        m_valobj_list = valobj_list;
        const size_t num_values = m_valobj_list.GetSize();
        for (size_t i=0; i<num_values; ++i)
            m_rows.push_back(Row(m_valobj_list.GetValueObjectAtIndex(i), NULL));
    }
    
    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        m_num_rows = 0;
        m_min_x = 2;
        m_min_y = 1;
        m_max_x = window.GetWidth() - 1;
        m_max_y = window.GetHeight() - 1;
        
        window.Erase();
        window.DrawTitleBox (window.GetName());
        
        const int num_visible_rows = NumVisibleRows();
        const int num_rows = CalculateTotalNumberRows (m_rows);
        
        // If we unexpanded while having something selected our
        // total number of rows is less than the num visible rows,
        // then make sure we show all the rows by setting the first
        // visible row accordingly.
        if (m_first_visible_row > 0 && num_rows < num_visible_rows)
            m_first_visible_row = 0;
        
        // Make sure the selected row is always visible
        if (m_selected_row_idx < m_first_visible_row)
            m_first_visible_row = m_selected_row_idx;
        else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
            m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
        
        DisplayRows (window, m_rows, g_options);
        
        window.DeferredRefresh();
        
        // Get the selected row
        m_selected_row = GetRowForRowIndex (m_selected_row_idx);
        // Keep the cursor on the selected row so the highlight and the cursor
        // are always on the same line
        if (m_selected_row)
            window.MoveCursor (m_selected_row->x,
                               m_selected_row->y);
        
        return true; // Drawing handled
    }
    
    KeyHelp *
    WindowDelegateGetKeyHelp () override
    {
        static curses::KeyHelp g_source_view_key_help[] = {
            { KEY_UP, "Select previous item" },
            { KEY_DOWN, "Select next item" },
            { KEY_RIGHT, "Expand selected item" },
            { KEY_LEFT, "Unexpand selected item or select parent if not expanded" },
            { KEY_PPAGE, "Page up" },
            { KEY_NPAGE, "Page down" },
            { 'A', "Format as annotated address" },
            { 'b', "Format as binary" },
            { 'B', "Format as hex bytes with ASCII" },
            { 'c', "Format as character" },
            { 'd', "Format as a signed integer" },
            { 'D', "Format selected value using the default format for the type" },
            { 'f', "Format as float" },
            { 'h', "Show help dialog" },
            { 'i', "Format as instructions" },
            { 'o', "Format as octal" },
            { 'p', "Format as pointer" },
            { 's', "Format as C string" },
            { 't', "Toggle showing/hiding type names" },
            { 'u', "Format as an unsigned integer" },
            { 'x', "Format as hex" },
            { 'X', "Format as uppercase hex" },
            { ' ', "Toggle item expansion" },
            { ',', "Page up" },
            { '.', "Page down" },
            { '\0', NULL }
        };
        return g_source_view_key_help;
    }

    HandleCharResult
    WindowDelegateHandleChar (Window &window, int c) override
    {
        switch(c)
        {
            case 'x':
            case 'X':
            case 'o':
            case 's':
            case 'u':
            case 'd':
            case 'D':
            case 'i':
            case 'A':
            case 'p':
            case 'c':
            case 'b':
            case 'B':
            case 'f':
                // Change the format for the currently selected item
                if (m_selected_row)
                    m_selected_row->valobj->SetFormat (FormatForChar (c));
                return eKeyHandled;
                
            case 't':
                // Toggle showing type names
                g_options.show_types = !g_options.show_types;
                return eKeyHandled;
                
            case ',':
            case KEY_PPAGE:
                // Page up key
                if (m_first_visible_row > 0)
                {
                    if (static_cast<int>(m_first_visible_row) > m_max_y)
                        m_first_visible_row -= m_max_y;
                    else
                        m_first_visible_row = 0;
                    m_selected_row_idx = m_first_visible_row;
                }
                return eKeyHandled;
                
            case '.':
            case KEY_NPAGE:
                // Page down key
                if (m_num_rows > static_cast<size_t>(m_max_y))
                {
                    if (m_first_visible_row + m_max_y < m_num_rows)
                    {
                        m_first_visible_row += m_max_y;
                        m_selected_row_idx = m_first_visible_row;
                    }
                }
                return eKeyHandled;
                
            case KEY_UP:
                if (m_selected_row_idx > 0)
                    --m_selected_row_idx;
                return eKeyHandled;

            case KEY_DOWN:
                if (m_selected_row_idx + 1 < m_num_rows)
                    ++m_selected_row_idx;
                return eKeyHandled;
                
            case KEY_RIGHT:
                if (m_selected_row)
                {
                    if (!m_selected_row->expanded)
                        m_selected_row->Expand();
                }
                return eKeyHandled;
                
            case KEY_LEFT:
                if (m_selected_row)
                {
                    if (m_selected_row->expanded)
                        m_selected_row->Unexpand();
                    else if (m_selected_row->parent)
                        m_selected_row_idx = m_selected_row->parent->row_idx;
                }
                return eKeyHandled;
                
            case ' ':
                // Toggle expansion state when SPACE is pressed
                if (m_selected_row)
                {
                    if (m_selected_row->expanded)
                        m_selected_row->Unexpand();
                    else
                        m_selected_row->Expand();
                }
                return eKeyHandled;
                
            case 'h':
                window.CreateHelpSubwindow ();
                return eKeyHandled;

            default:
                break;
        }
        return eKeyNotHandled;
    }
    
protected:
    ValueObjectList m_valobj_list;
    std::vector<Row> m_rows;
    Row *m_selected_row;
    uint32_t m_selected_row_idx;
    uint32_t m_first_visible_row;
    uint32_t m_num_rows;
    int m_min_x;
    int m_min_y;
    int m_max_x;
    int m_max_y;

    static Format
    FormatForChar (int c)
    {
        switch (c)
        {
            case 'x': return eFormatHex;
            case 'X': return eFormatHexUppercase;
            case 'o': return eFormatOctal;
            case 's': return eFormatCString;
            case 'u': return eFormatUnsigned;
            case 'd': return eFormatDecimal;
            case 'D': return eFormatDefault;
            case 'i': return eFormatInstruction;
            case 'A': return eFormatAddressInfo;
            case 'p': return eFormatPointer;
            case 'c': return eFormatChar;
            case 'b': return eFormatBinary;
            case 'B': return eFormatBytesWithASCII;
            case 'f': return eFormatFloat;
        }
        return eFormatDefault;
    }
    
    bool
    DisplayRowObject (Window &window,
                      Row &row,
                      DisplayOptions &options,
                      bool highlight,
                      bool last_child)
    {
        ValueObject *valobj = row.valobj.get();
        
        if (valobj == NULL)
            return false;
    
        const char *type_name = options.show_types ? valobj->GetTypeName().GetCString() : NULL;
        const char *name = valobj->GetName().GetCString();
        const char *value = valobj->GetValueAsCString ();
        const char *summary = valobj->GetSummaryAsCString ();
        
        window.MoveCursor (row.x, row.y);
        
        row.DrawTree (window);
        
        if (highlight)
            window.AttributeOn(A_REVERSE);
        
        if (type_name && type_name[0])
            window.Printf ("(%s) ", type_name);
        
        if (name && name[0])
            window.PutCString(name);
        
        attr_t changd_attr = 0;
        if (valobj->GetValueDidChange())
            changd_attr = COLOR_PAIR(5) | A_BOLD;
        
        if (value && value[0])
        {
            window.PutCString(" = ");
            if (changd_attr)
                window.AttributeOn(changd_attr);
            window.PutCString (value);
            if (changd_attr)
                window.AttributeOff(changd_attr);
        }
        
        if (summary && summary[0])
        {
            window.PutChar(' ');
            if (changd_attr)
                window.AttributeOn(changd_attr);
            window.PutCString(summary);
            if (changd_attr)
                window.AttributeOff(changd_attr);
        }
        
        if (highlight)
            window.AttributeOff (A_REVERSE);
        
        return true;
    }

    void
    DisplayRows (Window &window,
                 std::vector<Row> &rows,
                 DisplayOptions &options)
    {
        // >   0x25B7
        // \/  0x25BD
        
        bool window_is_active = window.IsActive();
        for (auto &row : rows)
        {
            const bool last_child = row.parent && &rows[rows.size()-1] == &row;
            // Save the row index in each Row structure
            row.row_idx = m_num_rows;
            if ((m_num_rows >= m_first_visible_row) &&
                ((m_num_rows - m_first_visible_row) < static_cast<size_t>(NumVisibleRows())))
            {
                row.x = m_min_x;
                row.y = m_num_rows - m_first_visible_row + 1;
                if (DisplayRowObject (window,
                                      row,
                                      options,
                                      window_is_active && m_num_rows == m_selected_row_idx,
                                      last_child))
                {
                    ++m_num_rows;
                }
                else
                {
                    row.x = 0;
                    row.y = 0;
                }
            }
            else
            {
                row.x = 0;
                row.y = 0;
                ++m_num_rows;
            }
            
            if (row.expanded && !row.children.empty())
            {
                DisplayRows (window,
                             row.children,
                             options);
            }
        }
    }
    
    int
    CalculateTotalNumberRows (const std::vector<Row> &rows)
    {
        int row_count = 0;
        for (const auto &row : rows)
        {
            ++row_count;
            if (row.expanded)
                row_count += CalculateTotalNumberRows(row.children);
        }
        return row_count;
    }

    static Row *
    GetRowForRowIndexImpl (std::vector<Row> &rows, size_t &row_index)
    {
        for (auto &row : rows)
        {
            if (row_index == 0)
                return &row;
            else
            {
                --row_index;
                if (row.expanded && !row.children.empty())
                {
                    Row *result = GetRowForRowIndexImpl (row.children, row_index);
                    if (result)
                        return result;
                }
            }
        }
        return NULL;
    }
    
    Row *
    GetRowForRowIndex (size_t row_index)
    {
        return GetRowForRowIndexImpl (m_rows, row_index);
    }
    
    int
    NumVisibleRows () const
    {
        return m_max_y - m_min_y;
    }

    static DisplayOptions g_options;
};

class FrameVariablesWindowDelegate : public ValueObjectListDelegate
{
public:
    FrameVariablesWindowDelegate (Debugger &debugger) :
        ValueObjectListDelegate (),
        m_debugger (debugger),
        m_frame_block (NULL)
    {
    }

    ~FrameVariablesWindowDelegate() override = default;

    const char *
    WindowDelegateGetHelpText () override
    {
        return "Frame variable window keyboard shortcuts:";
    }
    
    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
        Process *process = exe_ctx.GetProcessPtr();
        Block *frame_block = NULL;
        StackFrame *frame = NULL;
        
        if (process)
        {
            StateType state = process->GetState();
            if (StateIsStoppedState(state, true))
            {
                frame = exe_ctx.GetFramePtr();
                if (frame)
                    frame_block = frame->GetFrameBlock ();
            }
            else if (StateIsRunningState(state))
            {
                return true; // Don't do any updating when we are running
            }
        }

        ValueObjectList local_values;
        if (frame_block)
        {
            // Only update the variables if they have changed
            if (m_frame_block != frame_block)
            {
                m_frame_block = frame_block;

                VariableList *locals = frame->GetVariableList(true);
                if (locals)
                {
                    const DynamicValueType use_dynamic = eDynamicDontRunTarget;
                    const size_t num_locals = locals->GetSize();
                    for (size_t i=0; i<num_locals; ++i)
                    {
                        ValueObjectSP value_sp = frame->GetValueObjectForFrameVariable (locals->GetVariableAtIndex(i), use_dynamic);
                        if (value_sp)
                        {
                            ValueObjectSP synthetic_value_sp = value_sp->GetSyntheticValue();
                            if (synthetic_value_sp)
                                local_values.Append(synthetic_value_sp);
                            else
                                local_values.Append(value_sp);

                        }
                    }
                    // Update the values
                    SetValues(local_values);
                }
            }
        }
        else
        {
            m_frame_block = NULL;
            // Update the values with an empty list if there is no frame
            SetValues(local_values);
        }
        
        return ValueObjectListDelegate::WindowDelegateDraw (window, force);
    }

protected:
    Debugger &m_debugger;
    Block *m_frame_block;
};

class RegistersWindowDelegate : public ValueObjectListDelegate
{
public:
    RegistersWindowDelegate (Debugger &debugger) :
        ValueObjectListDelegate (),
        m_debugger (debugger)
    {
    }

    ~RegistersWindowDelegate() override = default;

    const char *
    WindowDelegateGetHelpText () override
    {
        return "Register window keyboard shortcuts:";
    }

    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
        StackFrame *frame = exe_ctx.GetFramePtr();
        
        ValueObjectList value_list;
        if (frame)
        {
            if (frame->GetStackID() != m_stack_id)
            {
                m_stack_id = frame->GetStackID();
                RegisterContextSP reg_ctx (frame->GetRegisterContext());
                if (reg_ctx)
                {
                    const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
                    for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
                    {
                        value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx));
                    }
                }
                SetValues(value_list);
            }
        }
        else
        {
            Process *process = exe_ctx.GetProcessPtr();
            if (process && process->IsAlive())
                return true; // Don't do any updating if we are running
            else
            {
                // Update the values with an empty list if there
                // is no process or the process isn't alive anymore
                SetValues(value_list);
            }
        }
        return ValueObjectListDelegate::WindowDelegateDraw (window, force);
    }
    
protected:
    Debugger &m_debugger;
    StackID m_stack_id;
};

static const char *
CursesKeyToCString (int ch)
{
    static char g_desc[32];
    if (ch >= KEY_F0 && ch < KEY_F0 + 64)
    {
        snprintf(g_desc, sizeof(g_desc), "F%u", ch - KEY_F0);
        return g_desc;
    }
    switch (ch)
    {
        case KEY_DOWN:  return "down";
        case KEY_UP:    return "up";
        case KEY_LEFT:  return "left";
        case KEY_RIGHT: return "right";
        case KEY_HOME:  return "home";
        case KEY_BACKSPACE: return "backspace";
        case KEY_DL:        return "delete-line";
        case KEY_IL:        return "insert-line";
        case KEY_DC:        return "delete-char";
        case KEY_IC:        return "insert-char";
        case KEY_CLEAR:     return "clear";
        case KEY_EOS:       return "clear-to-eos";
        case KEY_EOL:       return "clear-to-eol";
        case KEY_SF:        return "scroll-forward";
        case KEY_SR:        return "scroll-backward";
        case KEY_NPAGE:     return "page-down";
        case KEY_PPAGE:     return "page-up";
        case KEY_STAB:      return "set-tab";
        case KEY_CTAB:      return "clear-tab";
        case KEY_CATAB:     return "clear-all-tabs";
        case KEY_ENTER:     return "enter";
        case KEY_PRINT:     return "print";
        case KEY_LL:        return "lower-left key";
        case KEY_A1:        return "upper left of keypad";
        case KEY_A3:        return "upper right of keypad";
        case KEY_B2:        return "center of keypad";
        case KEY_C1:        return "lower left of keypad";
        case KEY_C3:        return "lower right of keypad";
        case KEY_BTAB:      return "back-tab key";
        case KEY_BEG:       return "begin key";
        case KEY_CANCEL:    return "cancel key";
        case KEY_CLOSE:     return "close key";
        case KEY_COMMAND:   return "command key";
        case KEY_COPY:      return "copy key";
        case KEY_CREATE:    return "create key";
        case KEY_END:       return "end key";
        case KEY_EXIT:      return "exit key";
        case KEY_FIND:      return "find key";
        case KEY_HELP:      return "help key";
        case KEY_MARK:      return "mark key";
        case KEY_MESSAGE:   return "message key";
        case KEY_MOVE:      return "move key";
        case KEY_NEXT:      return "next key";
        case KEY_OPEN:      return "open key";
        case KEY_OPTIONS:   return "options key";
        case KEY_PREVIOUS:  return "previous key";
        case KEY_REDO:      return "redo key";
        case KEY_REFERENCE: return "reference key";
        case KEY_REFRESH:   return "refresh key";
        case KEY_REPLACE:   return "replace key";
        case KEY_RESTART:   return "restart key";
        case KEY_RESUME:    return "resume key";
        case KEY_SAVE:      return "save key";
        case KEY_SBEG:      return "shifted begin key";
        case KEY_SCANCEL:   return "shifted cancel key";
        case KEY_SCOMMAND:  return "shifted command key";
        case KEY_SCOPY:     return "shifted copy key";
        case KEY_SCREATE:   return "shifted create key";
        case KEY_SDC:       return "shifted delete-character key";
        case KEY_SDL:       return "shifted delete-line key";
        case KEY_SELECT:    return "select key";
        case KEY_SEND:      return "shifted end key";
        case KEY_SEOL:      return "shifted clear-to-end-of-line key";
        case KEY_SEXIT:     return "shifted exit key";
        case KEY_SFIND:     return "shifted find key";
        case KEY_SHELP:     return "shifted help key";
        case KEY_SHOME:     return "shifted home key";
        case KEY_SIC:       return "shifted insert-character key";
        case KEY_SLEFT:     return "shifted left-arrow key";
        case KEY_SMESSAGE:  return "shifted message key";
        case KEY_SMOVE:     return "shifted move key";
        case KEY_SNEXT:     return "shifted next key";
        case KEY_SOPTIONS:  return "shifted options key";
        case KEY_SPREVIOUS: return "shifted previous key";
        case KEY_SPRINT:    return "shifted print key";
        case KEY_SREDO:     return "shifted redo key";
        case KEY_SREPLACE:  return "shifted replace key";
        case KEY_SRIGHT:    return "shifted right-arrow key";
        case KEY_SRSUME:    return "shifted resume key";
        case KEY_SSAVE:     return "shifted save key";
        case KEY_SSUSPEND:  return "shifted suspend key";
        case KEY_SUNDO:     return "shifted undo key";
        case KEY_SUSPEND:   return "suspend key";
        case KEY_UNDO:      return "undo key";
        case KEY_MOUSE:     return "Mouse event has occurred";
        case KEY_RESIZE:    return "Terminal resize event";
#ifdef KEY_EVENT
        case KEY_EVENT:     return "We were interrupted by an event";
#endif
        case KEY_RETURN:    return "return";
        case ' ':           return "space";
        case '\t':          return "tab";
        case KEY_ESCAPE:    return "escape";
        default:
            if (isprint(ch))
                snprintf(g_desc, sizeof(g_desc), "%c", ch);
            else
                snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch);
            return g_desc;
    }
    return NULL;
}

HelpDialogDelegate::HelpDialogDelegate (const char *text, KeyHelp *key_help_array) :
    m_text (),
    m_first_visible_line (0)
{
    if (text && text[0])
    {
        m_text.SplitIntoLines(text);
        m_text.AppendString("");
    }
    if (key_help_array)
    {
        for (KeyHelp *key = key_help_array; key->ch; ++key)
        {
            StreamString key_description;
            key_description.Printf("%10s - %s", CursesKeyToCString(key->ch), key->description);
            m_text.AppendString(std::move(key_description.GetString()));
        }
    }
}

HelpDialogDelegate::~HelpDialogDelegate() = default;
    
bool
HelpDialogDelegate::WindowDelegateDraw (Window &window, bool force)
{
    window.Erase();
    const int window_height = window.GetHeight();
    int x = 2;
    int y = 1;
    const int min_y = y;
    const int max_y = window_height - 1 - y;
    const size_t num_visible_lines = max_y - min_y + 1;
    const size_t num_lines = m_text.GetSize();
    const char *bottom_message;
    if (num_lines <= num_visible_lines)
        bottom_message = "Press any key to exit";
    else
        bottom_message = "Use arrows to scroll, any other key to exit";
    window.DrawTitleBox(window.GetName(), bottom_message);
    while (y <= max_y)
    {
        window.MoveCursor(x, y);
        window.PutCStringTruncated(m_text.GetStringAtIndex(m_first_visible_line + y - min_y), 1);
        ++y;
    }
    return true;
}

HandleCharResult
HelpDialogDelegate::WindowDelegateHandleChar (Window &window, int key)
{
    bool done = false;
    const size_t num_lines = m_text.GetSize();
    const size_t num_visible_lines = window.GetHeight() - 2;
    
    if (num_lines <= num_visible_lines)
    {
        done = true;
        // If we have all lines visible and don't need scrolling, then any
        // key press will cause us to exit
    }
    else
    {
        switch (key)
        {
            case KEY_UP:
                if (m_first_visible_line > 0)
                    --m_first_visible_line;
                break;

            case KEY_DOWN:
                if (m_first_visible_line + num_visible_lines < num_lines)
                    ++m_first_visible_line;
                break;

            case KEY_PPAGE:
            case ',':
                if (m_first_visible_line > 0)
                {
                    if (static_cast<size_t>(m_first_visible_line) >= num_visible_lines)
                        m_first_visible_line -= num_visible_lines;
                    else
                        m_first_visible_line = 0;
                }
                break;

            case KEY_NPAGE:
            case '.':
                if (m_first_visible_line + num_visible_lines < num_lines)
                {
                    m_first_visible_line += num_visible_lines;
                    if (static_cast<size_t>(m_first_visible_line) > num_lines)
                        m_first_visible_line = num_lines - num_visible_lines;
                }
                break;

            default:
                done = true;
                break;
        }
    }
    if (done)
        window.GetParent()->RemoveSubWindow(&window);
    return eKeyHandled;
}

class ApplicationDelegate :
    public WindowDelegate,
    public MenuDelegate
{
public:
    enum {
        eMenuID_LLDB = 1,
        eMenuID_LLDBAbout,
        eMenuID_LLDBExit,
        
        eMenuID_Target,
        eMenuID_TargetCreate,
        eMenuID_TargetDelete,
        
        eMenuID_Process,
        eMenuID_ProcessAttach,
        eMenuID_ProcessDetach,
        eMenuID_ProcessLaunch,
        eMenuID_ProcessContinue,
        eMenuID_ProcessHalt,
        eMenuID_ProcessKill,
        
        eMenuID_Thread,
        eMenuID_ThreadStepIn,
        eMenuID_ThreadStepOver,
        eMenuID_ThreadStepOut,
        
        eMenuID_View,
        eMenuID_ViewBacktrace,
        eMenuID_ViewRegisters,
        eMenuID_ViewSource,
        eMenuID_ViewVariables,
        
        eMenuID_Help,
        eMenuID_HelpGUIHelp
    };

    ApplicationDelegate (Application &app, Debugger &debugger) :
        WindowDelegate (),
        MenuDelegate (),
        m_app (app),
        m_debugger (debugger)
    {
    }

    ~ApplicationDelegate() override = default;

    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        return false; // Drawing not handled, let standard window drawing happen
    }
    
    HandleCharResult
    WindowDelegateHandleChar (Window &window, int key) override
    {
        switch (key)
        {
            case '\t':
                window.SelectNextWindowAsActive();
                return eKeyHandled;

            case 'h':
                window.CreateHelpSubwindow();
                return eKeyHandled;

            case KEY_ESCAPE:
                return eQuitApplication;

            default:
                break;
        }
        return eKeyNotHandled;
    }

    const char *
    WindowDelegateGetHelpText () override
    {
        return "Welcome to the LLDB curses GUI.\n\n"
        "Press the TAB key to change the selected view.\n"
        "Each view has its own keyboard shortcuts, press 'h' to open a dialog to display them.\n\n"
        "Common key bindings for all views:";
    }
    
    KeyHelp *
    WindowDelegateGetKeyHelp () override
    {
        static curses::KeyHelp g_source_view_key_help[] = {
            { '\t', "Select next view" },
            { 'h', "Show help dialog with view specific key bindings" },
            { ',', "Page up" },
            { '.', "Page down" },
            { KEY_UP, "Select previous" },
            { KEY_DOWN, "Select next" },
            { KEY_LEFT, "Unexpand or select parent" },
            { KEY_RIGHT, "Expand" },
            { KEY_PPAGE, "Page up" },
            { KEY_NPAGE, "Page down" },
            { '\0', NULL }
        };
        return g_source_view_key_help;
    }
    
    MenuActionResult
    MenuDelegateAction (Menu &menu) override
    {
        switch (menu.GetIdentifier())
        {
            case eMenuID_ThreadStepIn:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
                            exe_ctx.GetThreadRef().StepIn(true);
                    }
                }
                return MenuActionResult::Handled;
                
            case eMenuID_ThreadStepOut:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
                            exe_ctx.GetThreadRef().StepOut();
                    }
                }
                return MenuActionResult::Handled;
                
            case eMenuID_ThreadStepOver:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
                            exe_ctx.GetThreadRef().StepOver(true);
                    }
                }
                return MenuActionResult::Handled;

            case eMenuID_ProcessContinue:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
                            process->Resume();
                    }
                }
                return MenuActionResult::Handled;

            case eMenuID_ProcessKill:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive())
                            process->Destroy(false);
                    }
                }
                return MenuActionResult::Handled;

            case eMenuID_ProcessHalt:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive())
                            process->Halt();
                    }
                }
                return MenuActionResult::Handled;

            case eMenuID_ProcessDetach:
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                    {
                        Process *process = exe_ctx.GetProcessPtr();
                        if (process && process->IsAlive())
                            process->Detach(false);
                    }
                }
                return MenuActionResult::Handled;

            case eMenuID_Process:
                {
                    // Populate the menu with all of the threads if the process is stopped when
                    // the Process menu gets selected and is about to display its submenu.
                    Menus &submenus = menu.GetSubmenus();
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    Process *process = exe_ctx.GetProcessPtr();
                    if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
                    {
                        if (submenus.size() == 7)
                            menu.AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
                        else if (submenus.size() > 8)
                            submenus.erase (submenus.begin() + 8, submenus.end());
                        
                        ThreadList &threads = process->GetThreadList();
                        Mutex::Locker locker (threads.GetMutex());
                        size_t num_threads = threads.GetSize();
                        for (size_t i=0; i<num_threads; ++i)
                        {
                            ThreadSP thread_sp = threads.GetThreadAtIndex(i);
                            char menu_char = '\0';
                            if (i < 9)
                                menu_char = '1' + i;
                            StreamString thread_menu_title;
                            thread_menu_title.Printf("Thread %u", thread_sp->GetIndexID());
                            const char *thread_name = thread_sp->GetName();
                            if (thread_name && thread_name[0])
                                thread_menu_title.Printf (" %s", thread_name);
                            else
                            {
                                const char *queue_name = thread_sp->GetQueueName();
                                if (queue_name && queue_name[0])
                                    thread_menu_title.Printf (" %s", queue_name);
                            }
                            menu.AddSubmenu (MenuSP (new Menu(thread_menu_title.GetString().c_str(), NULL, menu_char, thread_sp->GetID())));
                        }
                    }
                    else if (submenus.size() > 7)
                    {
                        // Remove the separator and any other thread submenu items
                        // that were previously added
                        submenus.erase (submenus.begin() + 7, submenus.end());
                    }
                    // Since we are adding and removing items we need to recalculate the name lengths
                    menu.RecalculateNameLengths();
                }
                return MenuActionResult::Handled;
                
            case eMenuID_ViewVariables:
                {
                    WindowSP main_window_sp = m_app.GetMainWindow();
                    WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
                    WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
                    WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
                    const Rect source_bounds = source_window_sp->GetBounds();

                    if (variables_window_sp)
                    {
                        const Rect variables_bounds = variables_window_sp->GetBounds();

                        main_window_sp->RemoveSubWindow(variables_window_sp.get());

                        if (registers_window_sp)
                        {
                            // We have a registers window, so give all the area back to the registers window
                            Rect registers_bounds = variables_bounds;
                            registers_bounds.size.width = source_bounds.size.width;
                            registers_window_sp->SetBounds(registers_bounds);
                        }
                        else
                        {
                            // We have no registers window showing so give the bottom
                            // area back to the source view
                            source_window_sp->Resize (source_bounds.size.width,
                                                      source_bounds.size.height + variables_bounds.size.height);
                        }
                    }
                    else
                    {
                        Rect new_variables_rect;
                        if (registers_window_sp)
                        {
                            // We have a registers window so split the area of the registers
                            // window into two columns where the left hand side will be the
                            // variables and the right hand side will be the registers
                            const Rect variables_bounds = registers_window_sp->GetBounds();
                            Rect new_registers_rect;
                            variables_bounds.VerticalSplitPercentage (0.50, new_variables_rect, new_registers_rect);
                            registers_window_sp->SetBounds (new_registers_rect);
                        }
                        else
                        {
                            // No variables window, grab the bottom part of the source window
                            Rect new_source_rect;
                            source_bounds.HorizontalSplitPercentage (0.70, new_source_rect, new_variables_rect);
                            source_window_sp->SetBounds (new_source_rect);
                        }
                        WindowSP new_window_sp = main_window_sp->CreateSubWindow ("Variables",
                                                                                  new_variables_rect,
                                                                                  false);
                        new_window_sp->SetDelegate (WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
                    }
                    touchwin(stdscr);
                }
                return MenuActionResult::Handled;

            case eMenuID_ViewRegisters:
                {
                    WindowSP main_window_sp = m_app.GetMainWindow();
                    WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
                    WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
                    WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
                    const Rect source_bounds = source_window_sp->GetBounds();

                    if (registers_window_sp)
                    {
                        if (variables_window_sp)
                        {
                            const Rect variables_bounds = variables_window_sp->GetBounds();

                            // We have a variables window, so give all the area back to the variables window
                            variables_window_sp->Resize (variables_bounds.size.width + registers_window_sp->GetWidth(),
                                                         variables_bounds.size.height);
                        }
                        else
                        {
                            // We have no variables window showing so give the bottom
                            // area back to the source view
                            source_window_sp->Resize (source_bounds.size.width,
                                                      source_bounds.size.height + registers_window_sp->GetHeight());
                        }
                        main_window_sp->RemoveSubWindow(registers_window_sp.get());
                    }
                    else
                    {
                        Rect new_regs_rect;
                        if (variables_window_sp)
                        {
                            // We have a variables window, split it into two columns
                            // where the left hand side will be the variables and the
                            // right hand side will be the registers
                            const Rect variables_bounds = variables_window_sp->GetBounds();
                            Rect new_vars_rect;
                            variables_bounds.VerticalSplitPercentage (0.50, new_vars_rect, new_regs_rect);
                            variables_window_sp->SetBounds (new_vars_rect);
                        }
                        else
                        {
                            // No registers window, grab the bottom part of the source window
                            Rect new_source_rect;
                            source_bounds.HorizontalSplitPercentage (0.70, new_source_rect, new_regs_rect);
                            source_window_sp->SetBounds (new_source_rect);
                        }
                        WindowSP new_window_sp = main_window_sp->CreateSubWindow ("Registers",
                                                                                  new_regs_rect,
                                                                                  false);
                        new_window_sp->SetDelegate (WindowDelegateSP(new RegistersWindowDelegate(m_debugger)));
                    }
                    touchwin(stdscr);
                }
                return MenuActionResult::Handled;
                
            case eMenuID_HelpGUIHelp:
                m_app.GetMainWindow ()->CreateHelpSubwindow();
                return MenuActionResult::Handled;
        
            default:
                break;
        }

        return MenuActionResult::NotHandled;
    }
protected:
    Application &m_app;
    Debugger &m_debugger;
};

class StatusBarWindowDelegate : public WindowDelegate
{
public:
    StatusBarWindowDelegate (Debugger &debugger) :
        m_debugger (debugger)
    {
        FormatEntity::Parse("Thread: ${thread.id%tid}",
                            m_format);
    }

    ~StatusBarWindowDelegate() override = default;

    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
        Process *process = exe_ctx.GetProcessPtr();
        Thread *thread = exe_ctx.GetThreadPtr();
        StackFrame *frame = exe_ctx.GetFramePtr();
        window.Erase();
        window.SetBackground(2);
        window.MoveCursor (0, 0);
        if (process)
        {
            const StateType state = process->GetState();
            window.Printf ("Process: %5" PRIu64 " %10s", process->GetID(), StateAsCString(state));

            if (StateIsStoppedState(state, true))
            {
                StreamString strm;
                if (thread && FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
                {
                    window.MoveCursor (40, 0);
                    window.PutCStringTruncated(strm.GetString().c_str(), 1);
                }

                window.MoveCursor (60, 0);
                if (frame)
                    window.Printf ("Frame: %3u  PC = 0x%16.16" PRIx64, frame->GetFrameIndex(), frame->GetFrameCodeAddress().GetOpcodeLoadAddress (exe_ctx.GetTargetPtr()));
            }
            else if (state == eStateExited)
            {
                const char *exit_desc = process->GetExitDescription();
                const int exit_status = process->GetExitStatus();
                if (exit_desc && exit_desc[0])
                    window.Printf (" with status = %i (%s)", exit_status, exit_desc);
                else
                    window.Printf (" with status = %i", exit_status);
            }
        }
        window.DeferredRefresh();
        return true;
    }

protected:
    Debugger &m_debugger;
    FormatEntity::Entry m_format;
};

class SourceFileWindowDelegate : public WindowDelegate
{
public:
    SourceFileWindowDelegate (Debugger &debugger) :
        WindowDelegate (),
        m_debugger (debugger),
        m_sc (),
        m_file_sp (),
        m_disassembly_scope (NULL),
        m_disassembly_sp (),
        m_disassembly_range (),
        m_title (),
        m_line_width (4),
        m_selected_line (0),
        m_pc_line (0),
        m_stop_id (0),
        m_frame_idx (UINT32_MAX),
        m_first_visible_line (0),
        m_min_x (0),
        m_min_y (0),
        m_max_x (0),
        m_max_y (0)
    {
    }

    ~SourceFileWindowDelegate() override = default;

    void
    Update (const SymbolContext &sc)
    {
        m_sc = sc;
    }

    uint32_t
    NumVisibleLines () const
    {
        return m_max_y - m_min_y;
    }

    const char *
    WindowDelegateGetHelpText () override
    {
        return "Source/Disassembly window keyboard shortcuts:";
    }

    KeyHelp *
    WindowDelegateGetKeyHelp () override
    {
        static curses::KeyHelp g_source_view_key_help[] = {
            { KEY_RETURN, "Run to selected line with one shot breakpoint" },
            { KEY_UP, "Select previous source line" },
            { KEY_DOWN, "Select next source line" },
            { KEY_PPAGE, "Page up" },
            { KEY_NPAGE, "Page down" },
            { 'b', "Set breakpoint on selected source/disassembly line" },
            { 'c', "Continue process" },
            { 'd', "Detach and resume process" },
            { 'D', "Detach with process suspended" },
            { 'h', "Show help dialog" },
            { 'k', "Kill process" },
            { 'n', "Step over (source line)" },
            { 'N', "Step over (single instruction)" },
            { 'o', "Step out" },
            { 's', "Step in (source line)" },
            { 'S', "Step in (single instruction)" },
            { ',', "Page up" },
            { '.', "Page down" },
            { '\0', NULL }
        };
        return g_source_view_key_help;
    }

    bool
    WindowDelegateDraw (Window &window, bool force) override
    {
        ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
        Process *process = exe_ctx.GetProcessPtr();
        Thread *thread = NULL;

        bool update_location = false;
        if (process)
        {
            StateType state = process->GetState();
            if (StateIsStoppedState(state, true))
            {
                // We are stopped, so it is ok to
                update_location = true;
            }
        }

        m_min_x = 1;
        m_min_y = 2;
        m_max_x = window.GetMaxX()-1;
        m_max_y = window.GetMaxY()-1;

        const uint32_t num_visible_lines = NumVisibleLines();
        StackFrameSP frame_sp;
        bool set_selected_line_to_pc = false;

        if (update_location)
        {
            const bool process_alive = process ? process->IsAlive() : false;
            bool thread_changed = false;
            if (process_alive)
            {
                thread = exe_ctx.GetThreadPtr();
                if (thread)
                {
                    frame_sp = thread->GetSelectedFrame();
                    auto tid = thread->GetID();
                    thread_changed = tid != m_tid;
                    m_tid = tid;
                }
                else
                {
                    if (m_tid != LLDB_INVALID_THREAD_ID)
                    {
                        thread_changed = true;
                        m_tid = LLDB_INVALID_THREAD_ID;
                    }
                }
            }
            const uint32_t stop_id = process ? process->GetStopID() : 0;
            const bool stop_id_changed = stop_id != m_stop_id;
            bool frame_changed = false;
            m_stop_id = stop_id;
            m_title.Clear();
            if (frame_sp)
            {
                m_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
                if (m_sc.module_sp)
                {
                    m_title.Printf("%s", m_sc.module_sp->GetFileSpec().GetFilename().GetCString());
                    ConstString func_name = m_sc.GetFunctionName();
                    if (func_name)
                        m_title.Printf("`%s", func_name.GetCString());
                }
                const uint32_t frame_idx = frame_sp->GetFrameIndex();
                frame_changed = frame_idx != m_frame_idx;
                m_frame_idx = frame_idx;
            }
            else
            {
                m_sc.Clear(true);
                frame_changed = m_frame_idx != UINT32_MAX;
                m_frame_idx = UINT32_MAX;
            }

            const bool context_changed = thread_changed || frame_changed || stop_id_changed;

            if (process_alive)
            {
                if (m_sc.line_entry.IsValid())
                {
                    m_pc_line = m_sc.line_entry.line;
                    if (m_pc_line != UINT32_MAX)
                        --m_pc_line; // Convert to zero based line number...
                    // Update the selected line if the stop ID changed...
                    if (context_changed)
                        m_selected_line = m_pc_line;

                    if (m_file_sp && m_file_sp->FileSpecMatches(m_sc.line_entry.file))
                    {
                        // Same file, nothing to do, we should either have the
                        // lines or not (source file missing)
                        if (m_selected_line >= static_cast<size_t>(m_first_visible_line))
                        {
                            if (m_selected_line >= m_first_visible_line + num_visible_lines)
                                m_first_visible_line = m_selected_line - 10;
                        }
                        else
                        {
                            if (m_selected_line > 10)
                                m_first_visible_line = m_selected_line - 10;
                            else
                                m_first_visible_line = 0;
                        }
                    }
                    else
                    {
                        // File changed, set selected line to the line with the PC
                        m_selected_line = m_pc_line;
                        m_file_sp = m_debugger.GetSourceManager().GetFile(m_sc.line_entry.file);
                        if (m_file_sp)
                        {
                            const size_t num_lines = m_file_sp->GetNumLines();
                            int m_line_width = 1;
                            for (size_t n = num_lines; n >= 10; n = n / 10)
                                ++m_line_width;

                            snprintf (m_line_format, sizeof(m_line_format), " %%%iu ", m_line_width);
                            if (num_lines < num_visible_lines || m_selected_line < num_visible_lines)
                                m_first_visible_line = 0;
                            else
                                m_first_visible_line = m_selected_line - 10;
                        }
                    }
                }
                else
                {
                    m_file_sp.reset();
                }

                if (!m_file_sp || m_file_sp->GetNumLines() == 0)
                {
                    // Show disassembly
                    bool prefer_file_cache = false;
                    if (m_sc.function)
                    {
                        if (m_disassembly_scope != m_sc.function)
                        {
                            m_disassembly_scope = m_sc.function;
                            m_disassembly_sp = m_sc.function->GetInstructions (exe_ctx, NULL, prefer_file_cache);
                            if (m_disassembly_sp)
                            {
                                set_selected_line_to_pc = true;
                                m_disassembly_range = m_sc.function->GetAddressRange();
                            }
                            else
                            {
                                m_disassembly_range.Clear();
                            }
                        }
                        else
                        {
                            set_selected_line_to_pc = context_changed;
                        }
                    }
                    else if (m_sc.symbol)
                    {
                        if (m_disassembly_scope != m_sc.symbol)
                        {
                            m_disassembly_scope = m_sc.symbol;
                            m_disassembly_sp = m_sc.symbol->GetInstructions (exe_ctx, NULL, prefer_file_cache);
                            if (m_disassembly_sp)
                            {
                                set_selected_line_to_pc = true;
                                m_disassembly_range.GetBaseAddress() = m_sc.symbol->GetAddress();
                                m_disassembly_range.SetByteSize(m_sc.symbol->GetByteSize());
                            }
                            else
                            {
                                m_disassembly_range.Clear();
                            }
                        }
                        else
                        {
                            set_selected_line_to_pc = context_changed;
                        }
                    }
                }
            }
            else
            {
                m_pc_line = UINT32_MAX;
            }
        }

        const int window_width = window.GetWidth();
        window.Erase();
        window.DrawTitleBox ("Sources");
        if (!m_title.GetString().empty())
        {
            window.AttributeOn(A_REVERSE);
            window.MoveCursor(1, 1);
            window.PutChar(' ');
            window.PutCStringTruncated(m_title.GetString().c_str(), 1);
            int x = window.GetCursorX();
            if (x < window_width - 1)
            {
                window.Printf ("%*s", window_width - x - 1, "");
            }
            window.AttributeOff(A_REVERSE);
        }

        Target *target = exe_ctx.GetTargetPtr();
        const size_t num_source_lines = GetNumSourceLines();
        if (num_source_lines > 0)
        {
            // Display source
            BreakpointLines bp_lines;
            if (target)
            {
                BreakpointList &bp_list = target->GetBreakpointList();
                const size_t num_bps = bp_list.GetSize();
                for (size_t bp_idx=0; bp_idx<num_bps; ++bp_idx)
                {
                    BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
                    const size_t num_bps_locs = bp_sp->GetNumLocations();
                    for (size_t bp_loc_idx=0; bp_loc_idx<num_bps_locs; ++bp_loc_idx)
                    {
                        BreakpointLocationSP bp_loc_sp = bp_sp->GetLocationAtIndex(bp_loc_idx);
                        LineEntry bp_loc_line_entry;
                        if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry (bp_loc_line_entry))
                        {
                            if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file)
                            {
                                bp_lines.insert(bp_loc_line_entry.line);
                            }
                        }
                    }
                }
            }

            const attr_t selected_highlight_attr = A_REVERSE;
            const attr_t pc_highlight_attr = COLOR_PAIR(1);

            for (size_t i=0; i<num_visible_lines; ++i)
            {
                const uint32_t curr_line = m_first_visible_line + i;
                if (curr_line < num_source_lines)
                {
                    const int line_y = m_min_y+i;
                    window.MoveCursor(1, line_y);
                    const bool is_pc_line = curr_line == m_pc_line;
                    const bool line_is_selected = m_selected_line == curr_line;
                    // Highlight the line as the PC line first, then if the selected line
                    // isn't the same as the PC line, highlight it differently
                    attr_t highlight_attr = 0;
                    attr_t bp_attr = 0;
                    if (is_pc_line)
                        highlight_attr = pc_highlight_attr;
                    else if (line_is_selected)
                        highlight_attr = selected_highlight_attr;

                    if (bp_lines.find(curr_line+1) != bp_lines.end())
                        bp_attr = COLOR_PAIR(2);

                    if (bp_attr)
                        window.AttributeOn(bp_attr);

                    window.Printf (m_line_format, curr_line + 1);

                    if (bp_attr)
                        window.AttributeOff(bp_attr);

                    window.PutChar(ACS_VLINE);
                    // Mark the line with the PC with a diamond
                    if (is_pc_line)
                        window.PutChar(ACS_DIAMOND);
                    else
                        window.PutChar(' ');

                    if (highlight_attr)
                        window.AttributeOn(highlight_attr);
                    const uint32_t line_len = m_file_sp->GetLineLength(curr_line + 1, false);
                    if (line_len > 0)
                        window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len);

                    if (is_pc_line && frame_sp && frame_sp->GetConcreteFrameIndex() == 0)
                    {
                        StopInfoSP stop_info_sp;
                        if (thread)
                            stop_info_sp = thread->GetStopInfo();
                        if (stop_info_sp)
                        {
                            const char *stop_description = stop_info_sp->GetDescription();
                            if (stop_description && stop_description[0])
                            {
                                size_t stop_description_len = strlen(stop_description);
                                int desc_x = window_width - stop_description_len - 16;
                                window.Printf ("%*s", desc_x - window.GetCursorX(), "");
                                //window.MoveCursor(window_width - stop_description_len - 15, line_y);
                                window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
                            }
                        }
                        else
                        {
                            window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
                        }
                    }
                    if (highlight_attr)
                        window.AttributeOff(highlight_attr);
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            size_t num_disassembly_lines = GetNumDisassemblyLines();
            if (num_disassembly_lines > 0)
            {
                // Display disassembly
                BreakpointAddrs bp_file_addrs;
                Target *target = exe_ctx.GetTargetPtr();
                if (target)
                {
                    BreakpointList &bp_list = target->GetBreakpointList();
                    const size_t num_bps = bp_list.GetSize();
                    for (size_t bp_idx=0; bp_idx<num_bps; ++bp_idx)
                    {
                        BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
                        const size_t num_bps_locs = bp_sp->GetNumLocations();
                        for (size_t bp_loc_idx=0; bp_loc_idx<num_bps_locs; ++bp_loc_idx)
                        {
                            BreakpointLocationSP bp_loc_sp = bp_sp->GetLocationAtIndex(bp_loc_idx);
                            LineEntry bp_loc_line_entry;
                            const lldb::addr_t file_addr = bp_loc_sp->GetAddress().GetFileAddress();
                            if (file_addr != LLDB_INVALID_ADDRESS)
                            {
                                if (m_disassembly_range.ContainsFileAddress(file_addr))
                                    bp_file_addrs.insert(file_addr);
                            }
                        }
                    }
                }

                const attr_t selected_highlight_attr = A_REVERSE;
                const attr_t pc_highlight_attr = COLOR_PAIR(1);

                StreamString strm;

                InstructionList &insts = m_disassembly_sp->GetInstructionList();
                Address pc_address;

                if (frame_sp)
                    pc_address = frame_sp->GetFrameCodeAddress();
                const uint32_t pc_idx = pc_address.IsValid() ? insts.GetIndexOfInstructionAtAddress (pc_address) : UINT32_MAX;
                if (set_selected_line_to_pc)
                {
                    m_selected_line = pc_idx;
                }

                const uint32_t non_visible_pc_offset = (num_visible_lines / 5);
                if (static_cast<size_t>(m_first_visible_line) >= num_disassembly_lines)
                    m_first_visible_line = 0;

                if (pc_idx < num_disassembly_lines)
                {
                    if (pc_idx < static_cast<uint32_t>(m_first_visible_line) ||
                        pc_idx >= m_first_visible_line + num_visible_lines)
                        m_first_visible_line = pc_idx - non_visible_pc_offset;
                }

                for (size_t i=0; i<num_visible_lines; ++i)
                {
                    const uint32_t inst_idx = m_first_visible_line + i;
                    Instruction *inst = insts.GetInstructionAtIndex(inst_idx).get();
                    if (!inst)
                        break;

                    const int line_y = m_min_y+i;
                    window.MoveCursor(1, line_y);
                    const bool is_pc_line = frame_sp && inst_idx == pc_idx;
                    const bool line_is_selected = m_selected_line == inst_idx;
                    // Highlight the line as the PC line first, then if the selected line
                    // isn't the same as the PC line, highlight it differently
                    attr_t highlight_attr = 0;
                    attr_t bp_attr = 0;
                    if (is_pc_line)
                        highlight_attr = pc_highlight_attr;
                    else if (line_is_selected)
                        highlight_attr = selected_highlight_attr;

                    if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) != bp_file_addrs.end())
                        bp_attr = COLOR_PAIR(2);

                    if (bp_attr)
                        window.AttributeOn(bp_attr);

                    window.Printf (" 0x%16.16llx ",
                                   static_cast<unsigned long long>(inst->GetAddress().GetLoadAddress(target)));

                    if (bp_attr)
                        window.AttributeOff(bp_attr);

                    window.PutChar(ACS_VLINE);
                    // Mark the line with the PC with a diamond
                    if (is_pc_line)
                        window.PutChar(ACS_DIAMOND);
                    else
                        window.PutChar(' ');

                    if (highlight_attr)
                        window.AttributeOn(highlight_attr);

                    const char *mnemonic = inst->GetMnemonic(&exe_ctx);
                    const char *operands = inst->GetOperands(&exe_ctx);
                    const char *comment = inst->GetComment(&exe_ctx);

                    if (mnemonic && mnemonic[0] == '\0')
                        mnemonic = NULL;
                    if (operands && operands[0] == '\0')
                        operands = NULL;
                    if (comment && comment[0] == '\0')
                        comment = NULL;

                    strm.Clear();

                    if (mnemonic && operands && comment)
                        strm.Printf ("%-8s %-25s ; %s", mnemonic, operands, comment);
                    else if (mnemonic && operands)
                        strm.Printf ("%-8s %s", mnemonic, operands);
                    else if (mnemonic)
                        strm.Printf ("%s", mnemonic);

                    int right_pad = 1;
                    window.PutCStringTruncated(strm.GetString().c_str(), right_pad);

                    if (is_pc_line && frame_sp && frame_sp->GetConcreteFrameIndex() == 0)
                    {
                        StopInfoSP stop_info_sp;
                        if (thread)
                            stop_info_sp = thread->GetStopInfo();
                        if (stop_info_sp)
                        {
                            const char *stop_description = stop_info_sp->GetDescription();
                            if (stop_description && stop_description[0])
                            {
                                size_t stop_description_len = strlen(stop_description);
                                int desc_x = window_width - stop_description_len - 16;
                                window.Printf ("%*s", desc_x - window.GetCursorX(), "");
                                //window.MoveCursor(window_width - stop_description_len - 15, line_y);
                                window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
                            }
                        }
                        else
                        {
                            window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
                        }
                    }
                    if (highlight_attr)
                        window.AttributeOff(highlight_attr);
                }
            }
        }
        window.DeferredRefresh();
        return true; // Drawing handled
    }

    size_t
    GetNumLines ()
    {
        size_t num_lines = GetNumSourceLines();
        if (num_lines == 0)
            num_lines = GetNumDisassemblyLines();
        return num_lines;
    }

    size_t
    GetNumSourceLines () const
    {
        if (m_file_sp)
            return m_file_sp->GetNumLines();
        return 0;
    }

    size_t
    GetNumDisassemblyLines () const
    {
        if (m_disassembly_sp)
            return m_disassembly_sp->GetInstructionList().GetSize();
        return 0;
    }

    HandleCharResult
    WindowDelegateHandleChar (Window &window, int c) override
    {
        const uint32_t num_visible_lines = NumVisibleLines();
        const size_t num_lines = GetNumLines ();

        switch (c)
        {
            case ',':
            case KEY_PPAGE:
                // Page up key
                if (static_cast<uint32_t>(m_first_visible_line) > num_visible_lines)
                    m_first_visible_line -= num_visible_lines;
                else
                    m_first_visible_line = 0;
                m_selected_line = m_first_visible_line;
                return eKeyHandled;

            case '.':
            case KEY_NPAGE:
                // Page down key
                {
                    if (m_first_visible_line + num_visible_lines < num_lines)
                        m_first_visible_line += num_visible_lines;
                    else if (num_lines < num_visible_lines)
                        m_first_visible_line = 0;
                    else
                        m_first_visible_line = num_lines - num_visible_lines;
                    m_selected_line = m_first_visible_line;
                }
                return eKeyHandled;

            case KEY_UP:
                if (m_selected_line > 0)
                {
                    m_selected_line--;
                    if (static_cast<size_t>(m_first_visible_line) > m_selected_line)
                        m_first_visible_line = m_selected_line;
                }
                return eKeyHandled;

            case KEY_DOWN:
                if (m_selected_line + 1 < num_lines)
                {
                    m_selected_line++;
                    if (m_first_visible_line + num_visible_lines < m_selected_line)
                        m_first_visible_line++;
                }
                return eKeyHandled;

            case '\r':
            case '\n':
            case KEY_ENTER:
                // Set a breakpoint and run to the line using a one shot breakpoint
                if (GetNumSourceLines() > 0)
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope() && exe_ctx.GetProcessRef().IsAlive())
                    {
                        BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (NULL,                      // Don't limit the breakpoint to certain modules
                                                                                      m_file_sp->GetFileSpec(),  // Source file
                                                                                      m_selected_line + 1,       // Source line number (m_selected_line is zero based)
                                                                                      eLazyBoolCalculate,        // Check inlines using global setting
                                                                                      eLazyBoolCalculate,        // Skip prologue using global setting,
                                                                                      false,                     // internal
                                                                                      false,                     // request_hardware
                                                                                      eLazyBoolCalculate);       // move_to_nearest_code
                        // Make breakpoint one shot
                        bp_sp->GetOptions()->SetOneShot(true);
                        exe_ctx.GetProcessRef().Resume();
                    }
                }
                else if (m_selected_line < GetNumDisassemblyLines())
                {
                    const Instruction *inst = m_disassembly_sp->GetInstructionList().GetInstructionAtIndex(m_selected_line).get();
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasTargetScope())
                    {
                        Address addr = inst->GetAddress();
                        BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (addr,     // lldb_private::Address
                                                                                      false,    // internal
                                                                                      false);   // request_hardware
                        // Make breakpoint one shot
                        bp_sp->GetOptions()->SetOneShot(true);
                        exe_ctx.GetProcessRef().Resume();
                    }
                }
                return eKeyHandled;

            case 'b':   // 'b' == toggle breakpoint on currently selected line
                if (m_selected_line < GetNumSourceLines())
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasTargetScope())
                    {
                        BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (NULL,                      // Don't limit the breakpoint to certain modules
                                                                                      m_file_sp->GetFileSpec(),  // Source file
                                                                                      m_selected_line + 1,       // Source line number (m_selected_line is zero based)
                                                                                      eLazyBoolCalculate,        // Check inlines using global setting
                                                                                      eLazyBoolCalculate,        // Skip prologue using global setting,
                                                                                      false,                     // internal
                                                                                      false,                     // request_hardware
                                                                                      eLazyBoolCalculate);       // move_to_nearest_code
                    }
                }
                else if (m_selected_line < GetNumDisassemblyLines())
                {
                    const Instruction *inst = m_disassembly_sp->GetInstructionList().GetInstructionAtIndex(m_selected_line).get();
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasTargetScope())
                    {
                        Address addr = inst->GetAddress();
                        BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (addr,     // lldb_private::Address
                                                                                      false,    // internal
                                                                                      false);   // request_hardware
                    }
                }
                return eKeyHandled;

            case 'd':   // 'd' == detach and let run
            case 'D':   // 'D' == detach and keep stopped
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                        exe_ctx.GetProcessRef().Detach(c == 'D');
                }
                return eKeyHandled;

            case 'k':
                // 'k' == kill
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                        exe_ctx.GetProcessRef().Destroy(false);
                }
                return eKeyHandled;

            case 'c':
                // 'c' == continue
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasProcessScope())
                        exe_ctx.GetProcessRef().Resume();
                }
                return eKeyHandled;

            case 'o':
                // 'o' == step out
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
                    {
                        exe_ctx.GetThreadRef().StepOut();
                    }
                }
                return eKeyHandled;

            case 'n':   // 'n' == step over
            case 'N':   // 'N' == step over instruction
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
                    {
                        bool source_step = (c == 'n');
                        exe_ctx.GetThreadRef().StepOver(source_step);
                    }
                }
                return eKeyHandled;

            case 's':   // 's' == step into
            case 'S':   // 'S' == step into instruction
                {
                    ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
                    if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
                    {
                        bool source_step = (c == 's');
                        exe_ctx.GetThreadRef().StepIn(source_step);
                    }
                }
                return eKeyHandled;

            case 'h':
                window.CreateHelpSubwindow ();
                return eKeyHandled;

            default:
                break;
        }
        return eKeyNotHandled;
    }

protected:
    typedef std::set<uint32_t> BreakpointLines;
    typedef std::set<lldb::addr_t> BreakpointAddrs;

    Debugger &m_debugger;
    SymbolContext m_sc;
    SourceManager::FileSP m_file_sp;
    SymbolContextScope *m_disassembly_scope;
    lldb::DisassemblerSP m_disassembly_sp;
    AddressRange m_disassembly_range;
    StreamString m_title;
    lldb::user_id_t m_tid;
    char m_line_format[8];
    int m_line_width;
    uint32_t m_selected_line;       // The selected line
    uint32_t m_pc_line;             // The line with the PC
    uint32_t m_stop_id;
    uint32_t m_frame_idx;
    int m_first_visible_line;
    int m_min_x;
    int m_min_y;
    int m_max_x;
    int m_max_y;
};

DisplayOptions ValueObjectListDelegate::g_options = { true };

IOHandlerCursesGUI::IOHandlerCursesGUI (Debugger &debugger) :
    IOHandler (debugger, IOHandler::Type::Curses)
{
}

void
IOHandlerCursesGUI::Activate ()
{
    IOHandler::Activate();
    if (!m_app_ap)
    {
        m_app_ap.reset (new Application (GetInputFILE(), GetOutputFILE()));

        // This is both a window and a menu delegate
        std::shared_ptr<ApplicationDelegate> app_delegate_sp(new ApplicationDelegate(*m_app_ap, m_debugger));
        
        MenuDelegateSP app_menu_delegate_sp = std::static_pointer_cast<MenuDelegate>(app_delegate_sp);
        MenuSP lldb_menu_sp(new Menu("LLDB" , "F1", KEY_F(1), ApplicationDelegate::eMenuID_LLDB));
        MenuSP exit_menuitem_sp(new Menu("Exit", NULL, 'x', ApplicationDelegate::eMenuID_LLDBExit));
        exit_menuitem_sp->SetCannedResult(MenuActionResult::Quit);
        lldb_menu_sp->AddSubmenu (MenuSP (new Menu("About LLDB", NULL, 'a', ApplicationDelegate::eMenuID_LLDBAbout)));
        lldb_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
        lldb_menu_sp->AddSubmenu (exit_menuitem_sp);
        
        MenuSP target_menu_sp(new Menu("Target" ,"F2", KEY_F(2), ApplicationDelegate::eMenuID_Target));
        target_menu_sp->AddSubmenu (MenuSP (new Menu("Create", NULL, 'c', ApplicationDelegate::eMenuID_TargetCreate)));
        target_menu_sp->AddSubmenu (MenuSP (new Menu("Delete", NULL, 'd', ApplicationDelegate::eMenuID_TargetDelete)));
        
        MenuSP process_menu_sp(new Menu("Process", "F3", KEY_F(3), ApplicationDelegate::eMenuID_Process));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Attach"  , NULL, 'a', ApplicationDelegate::eMenuID_ProcessAttach)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Detach"  , NULL, 'd', ApplicationDelegate::eMenuID_ProcessDetach)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Launch"  , NULL, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Continue", NULL, 'c', ApplicationDelegate::eMenuID_ProcessContinue)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Halt"    , NULL, 'h', ApplicationDelegate::eMenuID_ProcessHalt)));
        process_menu_sp->AddSubmenu (MenuSP (new Menu("Kill"    , NULL, 'k', ApplicationDelegate::eMenuID_ProcessKill)));
        
        MenuSP thread_menu_sp(new Menu("Thread", "F4", KEY_F(4), ApplicationDelegate::eMenuID_Thread));
        thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step In"  , NULL, 'i', ApplicationDelegate::eMenuID_ThreadStepIn)));
        thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Over", NULL, 'v', ApplicationDelegate::eMenuID_ThreadStepOver)));
        thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Out" , NULL, 'o', ApplicationDelegate::eMenuID_ThreadStepOut)));
        
        MenuSP view_menu_sp(new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View));
        view_menu_sp->AddSubmenu (MenuSP (new Menu("Backtrace", NULL, 'b', ApplicationDelegate::eMenuID_ViewBacktrace)));
        view_menu_sp->AddSubmenu (MenuSP (new Menu("Registers", NULL, 'r', ApplicationDelegate::eMenuID_ViewRegisters)));
        view_menu_sp->AddSubmenu (MenuSP (new Menu("Source"   , NULL, 's', ApplicationDelegate::eMenuID_ViewSource)));
        view_menu_sp->AddSubmenu (MenuSP (new Menu("Variables", NULL, 'v', ApplicationDelegate::eMenuID_ViewVariables)));
        
        MenuSP help_menu_sp(new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help));
        help_menu_sp->AddSubmenu (MenuSP (new Menu("GUI Help", NULL, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp)));
        
        m_app_ap->Initialize();
        WindowSP &main_window_sp = m_app_ap->GetMainWindow();
        
        MenuSP menubar_sp(new Menu(Menu::Type::Bar));
        menubar_sp->AddSubmenu (lldb_menu_sp);
        menubar_sp->AddSubmenu (target_menu_sp);
        menubar_sp->AddSubmenu (process_menu_sp);
        menubar_sp->AddSubmenu (thread_menu_sp);
        menubar_sp->AddSubmenu (view_menu_sp);
        menubar_sp->AddSubmenu (help_menu_sp);
        menubar_sp->SetDelegate(app_menu_delegate_sp);
        
        Rect content_bounds = main_window_sp->GetFrame();
        Rect menubar_bounds = content_bounds.MakeMenuBar();
        Rect status_bounds = content_bounds.MakeStatusBar();
        Rect source_bounds;
        Rect variables_bounds;
        Rect threads_bounds;
        Rect source_variables_bounds;
        content_bounds.VerticalSplitPercentage(0.80, source_variables_bounds, threads_bounds);
        source_variables_bounds.HorizontalSplitPercentage(0.70, source_bounds, variables_bounds);
        
        WindowSP menubar_window_sp = main_window_sp->CreateSubWindow("Menubar", menubar_bounds, false);
        // Let the menubar get keys if the active window doesn't handle the
        // keys that are typed so it can respond to menubar key presses.
        menubar_window_sp->SetCanBeActive(false); // Don't let the menubar become the active window
        menubar_window_sp->SetDelegate(menubar_sp);
        
        WindowSP source_window_sp (main_window_sp->CreateSubWindow("Source",
                                                                   source_bounds,
                                                                   true));
        WindowSP variables_window_sp (main_window_sp->CreateSubWindow("Variables",
                                                                      variables_bounds,
                                                                      false));
        WindowSP threads_window_sp (main_window_sp->CreateSubWindow("Threads",
                                                                      threads_bounds,
                                                                      false));
        WindowSP status_window_sp (main_window_sp->CreateSubWindow("Status",
                                                                   status_bounds,
                                                                   false));
        status_window_sp->SetCanBeActive(false); // Don't let the status bar become the active window
        main_window_sp->SetDelegate (std::static_pointer_cast<WindowDelegate>(app_delegate_sp));
        source_window_sp->SetDelegate (WindowDelegateSP(new SourceFileWindowDelegate(m_debugger)));
        variables_window_sp->SetDelegate (WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
        TreeDelegateSP thread_delegate_sp (new ThreadsTreeDelegate(m_debugger));
        threads_window_sp->SetDelegate (WindowDelegateSP(new TreeWindowDelegate(m_debugger, thread_delegate_sp)));
        status_window_sp->SetDelegate (WindowDelegateSP(new StatusBarWindowDelegate(m_debugger)));

        // Show the main help window once the first time the curses GUI is launched
        static bool g_showed_help = false;
        if (!g_showed_help)
        {
            g_showed_help = true;
            main_window_sp->CreateHelpSubwindow();
        }

        init_pair (1, COLOR_WHITE   , COLOR_BLUE  );
        init_pair (2, COLOR_BLACK   , COLOR_WHITE );
        init_pair (3, COLOR_MAGENTA , COLOR_WHITE );
        init_pair (4, COLOR_MAGENTA , COLOR_BLACK );
        init_pair (5, COLOR_RED     , COLOR_BLACK );
    }
}

void
IOHandlerCursesGUI::Deactivate ()
{
    m_app_ap->Terminate();
}

void
IOHandlerCursesGUI::Run ()
{
    m_app_ap->Run(m_debugger);
    SetIsDone(true);
}

IOHandlerCursesGUI::~IOHandlerCursesGUI() = default;

void
IOHandlerCursesGUI::Cancel ()
{
}

bool
IOHandlerCursesGUI::Interrupt ()
{
    return false;
}

void
IOHandlerCursesGUI::GotEOF()
{
}

#endif // LLDB_DISABLE_CURSES
