public static TreeNode addArrayItemToTree(PDFArray array, int i, TreeNode parentNode)
        {
            string   type, value;
            TreeNode curr = null;

            if (GetObjectTypeAndValue(array.Get(i), out type, out value))
            {
                if (parentNode.Nodes.Count > i)
                {
                    parentNode.Nodes.RemoveAt(i);
                }
                curr                  = parentNode.Nodes.Insert(i, value);
                curr.Tag              = array.Get(i);
                curr.ImageKey         = GetObjectIconName((PDFObject)curr.Tag);
                curr.SelectedImageKey = curr.ImageKey;

                // If it's an indirect object, append the ID and Generation numbers
                if ((curr.Tag != null) && ((curr.Tag as PDFObject).Indirect))
                {
                    curr.Text += (" [ID: " + (curr.Tag as PDFObject).ID
                                  + ", Gen: " + (curr.Tag as PDFObject).Generation + "]");
                }
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
            return(curr);
        }
        private void editSelectedArrayValue(PDFArray selectedArray, int index, object newValue)
        {
            PDFObject newPDFObject = createNewValueForSelectedScalar(selectedArray.Get(index), newValue.ToString());

            updateArrayValue(selectedArray, index, newPDFObject);
            //refresh the tree
            mainWindow.addArrayItemToTree(selectedArray, index, selectedNodeBeforeEdit);
            mainWindow.expandNode(selectedNodeBeforeEdit);
        }
        static void Main(string[] args)
        {
            Console.WriteLine("FormWalker Sample:");
            FileStream fs = new FileStream("FormWalkerOutput.log", FileMode.Create);
            // First, save the standard output.
            TextWriter   tmp = Console.Out;
            StreamWriter sw  = new StreamWriter(fs);

            Console.SetOut(sw);

            using (Library lib = new Library())
            {
                Console.WriteLine("Initialized the library.");

                String sInput1 = Library.ResourceDirectory + "Sample_Input/MultipleSignatures.pdf";
                if (args.Length > 0)
                {
                    sInput1 = args[0];
                }

                Document doc = new Document(sInput1);
                Console.WriteLine("Opened document " + sInput1);
                Console.WriteLine("");

                PDFObject form_entry = doc.Root.Get("AcroForm");
                if (form_entry is PDFDict)
                {
                    PDFDict form_root = (PDFDict)form_entry;
                    DisplayRootDictionary(form_root);

                    PDFObject fields_entry = form_root.Get("Fields");
                    if (fields_entry is PDFArray)
                    {
                        PDFArray fields = (PDFArray)fields_entry;
                        for (int i = 0; i < fields.Length; i++)
                        {
                            PDFObject field_entry = fields.Get(i);
                            enumerate_field(field_entry, "");
                        }
                    }
                }
                Console.SetOut(tmp);

                sw.Close();

                Console.WriteLine("Done.");
            }
        }
        // When an object is chosen in the tree, update the list view.
        private void mainTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
            {
                // Clear the existing data view
                clearDataGrid();

                // Clear the stream views
                streamViewCooked.Clear();
                streamViewRaw.Clear();

                // Special handling: If the user clicks the document icon, we should
                // do nothing.  Anything else in the tree is a PDFObject, so grab it
                // and put its contents in the list view
                if (e.Node.Text == "Document" || e.Node.Text == "(no document)")
                {
                    return;
                }
                // Must be a PDFObject; extract it from the tree node
                PDFObject obj = (e.Node.Tag as PDFObject);

                // Select what to do based on the object subtype
                if (obj is PDFInteger)
                {
                    SetHeadersForScalar();
                    string[] row1 = new string[] { "Int", (obj as PDFInteger).Value.ToString() };
                    dataGridView.Rows.Add(row1);
                }
                else if (obj is PDFBoolean)
                {
                    SetHeadersForScalar();
                    string[] row1 = new string[] { "Bool", (obj as PDFBoolean).Value.ToString() };
                    dataGridView.Rows.Add(row1);
                }
                else if (obj is PDFReal)
                {
                    SetHeadersForScalar();
                    string[] row1 = new string[] { "Real", (obj as PDFReal).Value.ToString() };
                    dataGridView.Rows.Add(row1);
                }
                else if (obj is PDFName)
                {
                    SetHeadersForScalar();
                    string[] row1 = new string[] { "Name", (obj as PDFName).Value };
                    dataGridView.Rows.Add(row1);
                }
                else if (obj is PDFString)
                {
                    SetHeadersForScalar();
                    string[] row1 = new string[] { "String", (obj as PDFString).Value };
                    dataGridView.Rows.Add(row1);
                }
                else if (obj is PDFArray)
                {
                    PDFArray array = (obj as PDFArray);
                    SetHeadersForArray();

                    for (int i = 0; i < array.Length; i++)
                    {
                        PDFObject subobj = array.Get(i);
                        String    type;
                        String    value;

                        // Interrogate the object for its type and value
                        GetObjectTypeAndValue(subobj, out type, out value);
                        string[] row = new string[] { "[" + i.ToString() + "]", type, value };
                        dataGridView.Rows.Add(row);
                    }
                }
                else if (obj is PDFDict)
                {
                    SetHeadersForDict();
                    (obj as PDFDict).EnumPDFObjects(new EnumObjectsForDataGrid(dataGridView));
                }
                else if (obj is PDFStream)
                {
                    SetHeadersForDict();
                    PDFStream streamobj = (obj as PDFStream);

                    // Put the dictionary into the list view
                    streamobj.Dict.EnumPDFObjects(new EnumObjectsForDataGrid(dataGridView));

                    System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(streamobj.UnfilteredStream);
                    byte[] buffer = binaryReader.ReadBytes(streamobj.Length);
                    streamViewRaw.Tag  = new StreamDataDisplayModePair(buffer, DisplayMode.String);
                    streamViewRaw.Text = convertToRawStringDisplay(buffer);

                    binaryReader          = new System.IO.BinaryReader(streamobj.FilteredStream);
                    buffer                = readAllBytesFromBinaryReader(binaryReader, 256);
                    streamViewCooked.Tag  = new StreamDataDisplayModePair(buffer, DisplayMode.String);
                    streamViewCooked.Text = convertToCookedStringDisplay(buffer);
                }
                else if (obj == null)
                {
                    return; // Do nothing for null objects -- they can legally appear in PDFArrays
                }
                else
                {
                    MessageBox.Show("This data type not recognized");
                }
            }
        }
        static void enumerate_field(PDFObject field_entry, string prefix)
        {
            string name_part;
            string field_name;
            string alternate_name = null;
            string mapping_name   = null;
            string field_type;

            string[]  field_info             = null;
            int       field_flags            = 0;
            bool      additional_actions     = false;
            bool      javascript_formatting  = false;
            bool      javascript_calculation = false;
            bool      javascript_validation  = false;
            PDFObject entry;

            if (field_entry is PDFDict)
            {
                PDFDict field = (PDFDict)field_entry;
                entry = (PDFString)field.Get("T");
                if (entry is PDFString)
                {
                    PDFString t = (PDFString)entry;
                    name_part = t.Value;
                }
                else
                {
                    return;
                }

                if (prefix == "")
                {
                    field_name = name_part;
                }
                else
                {
                    field_name = string.Format("{0}.{1}", prefix, name_part);
                }

                entry = field.Get("Kids");
                if (entry is PDFArray)
                {
                    PDFArray kids = (PDFArray)entry;
                    for (int i = 0; i < kids.Length; i++)
                    {
                        PDFObject kid_entry = kids.Get(i);
                        enumerate_field(kid_entry, field_name);
                    }
                }
                else //no kids, so we are at an end-node.
                {
                    Console.WriteLine("Name: " + field_name);

                    entry = field.Get("TU");
                    if (entry is PDFString)
                    {
                        PDFString tu = (PDFString)entry;
                        alternate_name = tu.Value;
                    }

                    entry = field.Get("TM");
                    if (entry is PDFString)
                    {
                        PDFString tm = (PDFString)entry;
                        mapping_name = tm.Value;
                    }

                    entry = field.Get("Ff");
                    if (entry is PDFInteger)
                    {
                        PDFInteger ff = (PDFInteger)entry;
                        field_flags = ff.Value;
                    }

                    entry = field.Get("AA");
                    if (entry is PDFDict)
                    {
                        additional_actions = true;
                        var aadict = entry as PDFDict;
                        javascript_formatting  = aadict.Contains("F");
                        javascript_calculation = aadict.Contains("C");
                        javascript_validation  = aadict.Contains("V");
                    }

                    entry = field.Get("FT");
                    if (entry is PDFName)
                    {
                        PDFName field_type_name = (PDFName)entry;
                        switch (field_type_name.Value)
                        {
                        case "Btn": field_type = "Button"; field_info = get_button_info(field); break;

                        case "Tx": field_type = "Text"; field_info = get_text_info(field); break;

                        case "Ch": field_type = "Choice"; field_info = get_choice_info(field); break;

                        case "Sig": field_type = "Signature"; field_info = get_sig_info(field); break;

                        default: field_type = field_type_name.Value; return;
                        }
                    }
                    else
                    {
                        field_type = "None";
                    }

                    if (alternate_name != null)
                    {
                        Console.WriteLine("Alternate Name: " + alternate_name);
                    }
                    if (mapping_name != null)
                    {
                        Console.WriteLine("Mapping Name: " + mapping_name);
                    }
                    if (additional_actions)
                    {
                        Console.WriteLine("Additional Actions: Javascript {0}{1}{2}.",
                                          javascript_validation?"Validation, ":"",
                                          javascript_calculation?"Calculation, ":"",
                                          javascript_formatting?"Formatting":"");
                    }

                    Console.WriteLine("Type: " + field_type);

                    if (field_flags != 0)
                    {
                        bool[] flags = new bool[28];
                        for (int bitpos = 1; bitpos < flags.Length; bitpos++)
                        {
                            flags[bitpos] = (0 != (field_flags & (0x1 << bitpos - 1)));
                        }
                        if (field_type == "Signature")
                        {
                            Console.WriteLine(String.Format("Signature Flags: {0:x8}: requires {1}{2}{3}{4}{5}{6}{7}", field_flags,
                                                            flags[1]?"Filter, ":"",
                                                            flags[2]?"SubFilter, ":"",
                                                            flags[3]?"V, ":"",
                                                            flags[4]?"Reason, ":"",
                                                            flags[5]?"LegalAttestation, ":"",
                                                            flags[6]?"AddRevInfo, ":"",
                                                            flags[7]?"DigestMethod":""
                                                            ));
                        }
                        else
                        {
                            Console.WriteLine(String.Format("Format Flags: {0:x8}: {1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}{17}{18}", field_flags,
                                                            flags[1]?"ReadOnly ":"",
                                                            flags[2]?"Required ":"",
                                                            flags[3]?"NoExport ":"",
                                                            flags[13]?"MultiLine ":"",
                                                            flags[14]?"Password ":"",
                                                            flags[15]?"NoToggleToOff ":"",
                                                            flags[16]?"Radio ":"",
                                                            flags[17]?"PushButton ":"",
                                                            flags[18]?"Combo ":"",
                                                            flags[19]?"Edit ":"",
                                                            flags[20]?"Sort ":"",
                                                            flags[21]?"FileSelect ":"",
                                                            flags[22]?"MultiSelect ":"",
                                                            flags[23]?"DoNotSpellCheck ":"",
                                                            flags[24]?"DoNotScroll ":"",
                                                            flags[25]?"Comb ":"",
                                                            flags[26]?(field_type == "Text"?"RichText":(field_type == "Button"?"RadiosInUnison":"?")):"",
                                                            flags[27]?"CommitOnSelChange ":""
                                                            ));
                        }
                    }

                    foreach (string item in field_info)
                    {
                        if (item != "")
                        {
                            Console.WriteLine(item);
                        }
                    }
                    Console.WriteLine("");
                }
            }
        }