/// <summary>
        /// Shows the difference between the two JSON objects a and b.
        /// Diff is the computed difference between the objects.
        /// If json is set to true, the output is showed in JSON format,
        /// otherwise SJSON format is used.
        /// </summary>
        public DiffVisualForm(Hashtable a, Hashtable b, HashDiff diff, bool json)
        {
            InitializeComponent();

            _json = json;
            if (_json)
            {
                _af = new JsonFormatter();
                _bf = new JsonFormatter();
            }
            else
            {
                _af = new SjsonFormatter();
                _bf = new SjsonFormatter();
            }

            _diff_lines.Add(0);

            // Enforce object creation (you can get a highlighting bug otherwise).
            IntPtr ah = aTextBox.Handle;
            IntPtr bh = bTextBox.Handle;

            if (_json)
            {
                SameText("{", "{");
                DisplayDiff(a, b, diff, 1);
                SameText("\n}", "\n}");
            }
            else
            {
                DisplayDiff(a, b, diff, 0);
            }

            _diff_lines.Add(aTextBox.Lines.Count());

            aTextBox.SelectionStart  = 0;
            aTextBox.SelectionLength = 0;
            bTextBox.SelectionStart  = 0;
            bTextBox.SelectionLength = 0;
        }
        public MergeVisualForm(Hashtable parent, Hashtable a, HashDiff adiff,
                               Hashtable b, HashDiff bdiff, Hashtable c, HashDiff cdiff, bool json)
        {
            InitializeComponent();

            _json = json;
            if (_json)
            {
                _af = new JsonFormatter();
                _bf = new JsonFormatter();
                _cf = new JsonFormatter();
            }
            else
            {
                _af = new SjsonFormatter();
                _bf = new SjsonFormatter();
                _cf = new SjsonFormatter();
            }

            // Enforce object creation (you can get a highlighting bug otherwise).
            IntPtr ah = aTextBox.Handle;
            IntPtr bh = bTextBox.Handle;
            IntPtr ch = cTextBox.Handle;

            // This while loop is a rather ugly thing.
            //
            // We use the _line_number Dictionary to store the highest line number where
            // a particular key path (e.g. items.size.x) have been displayed in any of the
            // views. When a view wants to display a particular key, it pads the text with
            // newlines so that the key appears at the maximum line number where it has
            // appeared before. If the current line number is higher than the previous
            // maximum, the _line_number Dictionary is updated with the new maximum and
            // _line_numbers_changed is true.
            //
            // By looping here and reformatting the text until _line_number is no longer
            // changing we ensure that all keys are displayed at the same line in all three
            // views, so that we can scroll them simultaneously.
            //
            // In theory, this could take quite some time for the worst-case scenario and
            // it would be better to rewrite the code so that we are formatting the three views
            // simultaneously, padding with newlines as we go along. However, that is rather
            // hairy to write and this seems to work well for now.
            do
            {
                _diff_lines_set.Clear();

                aTextBox.Text         = "";
                bTextBox.Text         = "";
                cTextBox.Text         = "";
                _line_numbers_changed = false;
                int indent = 0;

                if (_json)
                {
                    SameText(aTextBox, "{");
                    SameText(bTextBox, "{");
                    SameText(cTextBox, "{");
                    indent = 1;
                }

                DisplayDiff(aTextBox, _af, parent, a, adiff, indent, "");
                DisplayDiff(bTextBox, _bf, parent, b, bdiff, indent, "");
                DisplayDiff(cTextBox, _cf, parent, c, cdiff, indent, "");

                if (_json)
                {
                    SameText(aTextBox, "\n}");
                    SameText(bTextBox, "\n}");
                    SameText(cTextBox, "\n}");
                }
            } while (_line_numbers_changed);

            _diff_lines_set.Add(0);
            _diff_lines_set.Add(aTextBox.Lines.Count());
            _diff_lines   = _diff_lines_set.OrderBy(i => i).ToList();
            _current_diff = 0;

            aTextBox.SelectionStart  = 0;
            aTextBox.SelectionLength = 0;
            bTextBox.SelectionStart  = 0;
            bTextBox.SelectionLength = 0;
            cTextBox.SelectionStart  = 0;
            cTextBox.SelectionLength = 0;
        }