Summary description for iRuleInfo.
        private void treeView_iRules_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode tn = getCurrentItem();
            // update last list view item with updates
            if ((null != m_lastTreeViewNode) && (m_lastTreeViewNode != tn))
            {
                iRuleInfo iri = (iRuleInfo)m_lastTreeViewNode.Tag;
                if (null != iri)
                {
                    iri.rule_details = m_textEditor.Text;
                }
            }

            if (null != tn)
            {
                m_lastTreeViewNode = tn;
                iRuleInfo iri = (iRuleInfo)tn.Tag;
                if (null != iri)
                {
                    m_iri = iri;
                    monitorNotifications(false);
                    m_textEditor.Text = iri.rule_details;
                    monitorNotifications(true);
                }
                else
                {
                    m_textEditor.Text = "";
                }
                updateTitle(false);
                showButtons(Clients.Connected);
                m_textEditor.EmptyUndoBuffer();
            }
        }
        private void refreshiRules()
        {
            if (Clients.Connected)
            {
                //treeView_iRules.Nodes.Clear();
                treeView_iRules.Nodes.Remove(m_treeNodeConfiguration);
                treeView_iRules.Nodes.Remove(m_treeNodeGlobalLB);
                treeView_iRules.Nodes.Remove(m_treeNodeLocalLB);

                m_treeNodeLocalLB.ImageIndex = 1;
                m_treeNodeLocalLB.SelectedImageIndex = 1;
                m_treeNodeGlobalLB.ImageIndex = 2;
                m_treeNodeGlobalLB.SelectedImageIndex = 2;
                if (m_configurationEditing)
                {
                    m_treeNodeConfiguration.ImageIndex = 4;
                    m_treeNodeConfiguration.SelectedImageIndex = 4;
                }

                //if (0 == treeView_iRules.Nodes.Count)
                //{
                    treeView_iRules.Nodes.Add(m_treeNodeLocalLB);
                    if (Clients.ConnectionInfo.getGTMLicensed())
                    {
                        treeView_iRules.Nodes.Add(m_treeNodeGlobalLB);
                    }
                //}

                m_treeNodeLocalLB.Nodes.Clear();
                if (Clients.ConnectionInfo.getGTMLicensed())
                {
                    m_treeNodeGlobalLB.Nodes.Clear();
                }

                if (m_configurationEditing)
                {
                    treeView_iRules.Nodes.Add(m_treeNodeConfiguration);
                    m_treeNodeConfiguration.Nodes.Clear();
                }
                if (m_offlineEditing)
                {
                    m_treeNodeOffline.Nodes.Clear();
                }

                // Query LocalLB Rules

                iControl.LocalLBRuleRuleDefinition[] rule_defs = Clients.Rule.query_all_rules();
                //Array.Sort(rule_defs, new iRuler.Utility.LocalLBiRuleDefinitionComparer());

                String [] rule_descriptions = null;

                try
                {
                    String[] rule_names = Clients.Rule.get_list();
                    rule_descriptions = Clients.Rule.get_description(rule_names);
                }
                catch (Exception)
                {
                }

                for (int i = 0; i < rule_defs.Length; i++)
                {
                    //if (0 != rule_defs[i].rule_name.IndexOf("_sys_"))
                    if ( ! (rule_defs[i].rule_name.StartsWith("_sys_")) && ! (rule_defs[i].rule_name.Contains("/_sys_")) )
                    {
                        TreeNode tn = new TreeNode();
                        iRuleInfo iri = new iRuleInfo(rule_defs[i].rule_name, rule_defs[i].rule_definition, false);
                        iri.rule_type = iRuleInfo.RuleType.LOCALLB;
                        tn.Text = rule_defs[i].rule_name;
                        tn.Tag = iri;
                        tn.NodeFont = treeView_iRules.Font;
                        tn.NodeFont = new System.Drawing.Font(tn.NodeFont, FontStyle.Regular);
                        //treeView_iRules.Nodes.Add(tn);
                        if ( null != rule_descriptions )
                        {
                            if (0 != rule_descriptions[i].Length)
                            {
                                tn.ToolTipText = rule_descriptions[i];
                            }
                            else
                            {
                                tn.ToolTipText = "No Description. Why don't you set one in the properties?";
                            }
                        }
                        m_treeNodeLocalLB.Nodes.Add(tn);
                    }
                }
                m_treeNodeLocalLB.Expand();

                // Query GlobalLB Rules

                if (Clients.ConnectionInfo.getGTMLicensed())
                {
                    iControl.GlobalLBRuleRuleDefinition[] glb_rule_defs = Clients.GlobalLBRule.query_all_rules();
                    //Array.Sort(glb_rule_defs, new iRuler.Utility.GlobalLBiRuleDefinitionComparer());

                    for (int i = 0; i < glb_rule_defs.Length; i++)
                    {
                        if (0 != glb_rule_defs[i].rule_name.IndexOf("_"))
                        {
                            TreeNode tn = new TreeNode();
                            iRuleInfo iri = new iRuleInfo(glb_rule_defs[i].rule_name, glb_rule_defs[i].rule_definition, false);
                            iri.rule_type = iRuleInfo.RuleType.GLOBALLB;
                            tn.Text = glb_rule_defs[i].rule_name;
                            tn.Tag = iri;
                            tn.NodeFont = treeView_iRules.Font;
                            tn.NodeFont = new System.Drawing.Font(tn.NodeFont, FontStyle.Regular);
                            //treeView_iRules.Nodes.Add(tn);
                            m_treeNodeGlobalLB.Nodes.Add(tn);
                        }
                    }
                    m_treeNodeGlobalLB.Expand();
                }

                // Query the Configurations
                if (m_configurationEditing)
                {
                    try
                    {
                        string remote_file = "/config/bigip.conf";
                        string conf = iRuler.Utility.FileTransfer.downloadFile(Clients.Interfaces, remote_file);
                        TreeNode tnc = new TreeNode();
                        iRuleInfo iric = new iRuleInfo(remote_file, conf, false);
                        iric.rule_type = iRuleInfo.RuleType.CONFIG;
                        tnc.Text = "bigip.conf";
                        tnc.Tag = iric;
                        tnc.NodeFont = treeView_iRules.Font;
                        tnc.NodeFont = new System.Drawing.Font(tnc.NodeFont, FontStyle.Regular);
                        m_treeNodeConfiguration.Nodes.Add(tnc);

                        remote_file = "/config/bigip_base.conf";
                        conf = iRuler.Utility.FileTransfer.downloadFile(Clients.Interfaces, remote_file);
                        tnc = new TreeNode();
                        iric = new iRuleInfo(remote_file, conf, false);
                        iric.rule_type = iRuleInfo.RuleType.CONFIG;
                        tnc.Text = "bigip_base.conf";
                        tnc.Tag = iric;
                        tnc.NodeFont = treeView_iRules.Font;
                        tnc.NodeFont = new System.Drawing.Font(tnc.NodeFont, FontStyle.Regular);
                        m_treeNodeConfiguration.Nodes.Add(tnc);
                    }
                    catch (Exception)
                    {
                        // User most likely doesn't have privileges to download files...
                    }
                }

                // TODO: Query the offline iRules

                m_textEditor.Text = "";
            }
            else
            {
                m_treeNodeOffline.Nodes.Clear();
            }
            if (m_offlineEditing)
            {
                refreshOffline();
            }
        }
        private bool DoSave()
        {
            bool bSaved = false;
            TreeNode tn = getCurrentItem();

            if ( Clients.Connected || (tn.Parent == m_treeNodeOffline) )
            {
                if (null == tn)
                {
                    ValuePromptDialog vpd = new ValuePromptDialog();
                    vpd.Title = "New iRule";
                    vpd.Description = "You are working in the offline buffer.  Please enter a name for your new iRule";
                    DialogResult dr = vpd.ShowDialog();
                    if (DialogResult.OK == dr)
                    {
                        String sRule = vpd.Value;
                        String sRuleDef = m_textEditor.Text;

                        tn = new TreeNode();
                        tn.Text = sRule;
                        tn.NodeFont = treeView_iRules.Font;
                        iRuleInfo iri = new iRuleInfo(sRule, sRuleDef, true);
                        tn.Tag = iri;
                        tn.ImageIndex = 0;
                        int index = treeView_iRules.Nodes.Add(tn);
                        // TODO
                        //tn.IsSelected = true;
                        treeView_iRules.SelectedNode = tn;
                        treeView_iRules.Select();
                        treeView_iRules.Focus();
                    }
                }

                if (null != tn)
                {
                    iRuleInfo iri = (iRuleInfo)tn.Tag;
                    if (null != iri)
                    {
                        iri.rule_details = m_textEditor.Text;
                        bSaved = DoSaveNode(tn);
                    }
                }
            }

            if (bSaved)
            {
                DoSaveConfiguration();
            }

            return bSaved;
        }
        private bool DoNew()
        {
            bool bNew = false;
            PromptDialog pd = new PromptDialog();

            // build a list of existing iRule Names
            String[] iRuleNames = new String[m_treeNodeGlobalLB.Nodes.Count + m_treeNodeLocalLB.Nodes.Count];
            for (int i = 0; i < m_treeNodeGlobalLB.Nodes.Count; i++)
            {
                iRuleNames[i] = m_treeNodeGlobalLB.Nodes[i].Text;
            }
            for (int i = 0; i < m_treeNodeLocalLB.Nodes.Count; i++)
            {
                iRuleNames[m_treeNodeGlobalLB.Nodes.Count + i] = m_treeNodeLocalLB.Nodes[i].Text;
            }
            pd.m_existingiRules = iRuleNames;

            DialogResult dr = pd.ShowDialog();
            if ( DialogResult.OK == dr )
            {
                String sRule = pd.m_ruleName;
                String sRuleDef = "when HTTP_REQUEST {\n}";
                if ( pd.m_ruleDefault.Length > 0 )
                {
                    sRuleDef = pd.m_ruleDefault;
                }

                TreeNode tn = new TreeNode();
                tn.Text = sRule + "*";
                tn.NodeFont = new System.Drawing.Font(treeView_iRules.Font, FontStyle.Regular);
                iRuleInfo iri = new iRuleInfo(sRule, sRuleDef, true);
                iri.rule_type = pd.m_ruleType;
                tn.Tag = iri;
                tn.ImageIndex = 0;
                //int index = treeView_iRules.Nodes.Add(tn);
                //treeView_iRules.Nodes.Insert(0,tn);
                TreeNode tnCurr = getCurrentItem();
                if (null != tnCurr)
                {
                    if (tnCurr.Parent == m_treeNodeOffline)
                    {
                        m_treeNodeOffline.Nodes.Insert(0, tn);
                    }
                    else if (!Clients.Connected)
                    {
                        m_treeNodeOffline.Nodes.Insert(0, tn);
                    }
                    else
                    {
                        switch (iri.rule_type)
                        {
                            case iRuleInfo.RuleType.GLOBALLB:
                                if (Clients.ConnectionInfo.getGTMLicensed())
                                {
                                    m_treeNodeGlobalLB.Nodes.Insert(0, tn);
                                }
                                break;
                            case iRuleInfo.RuleType.LOCALLB:
                            default:
                                m_treeNodeLocalLB.Nodes.Insert(0, tn);
                                break;
                        }
                    }
                }
                // TODO
                //tn.IsSelected = true;
                treeView_iRules.SelectedNode = tn;
                treeView_iRules.Select();
                treeView_iRules.Focus();

                markItem(tn, true);
            }
            return bNew;
        }
        private void DoDropFiles(String [] fileDropList, bool bPrompt, TreeNode tnParent)
        {
            if (null != fileDropList)
            {
                for (int i = 0; i < fileDropList.Length; i++)
                {
                    // Attempt to open file and create iRule based on the contents and name.
                    String fileName = System.IO.Path.GetFileNameWithoutExtension(fileDropList[i]);
                    String sContents = null;
                    bool bCreateNewNode = true;
                    bool bContinue = true;
                    try
                    {
                        fileName = FileNameToRuleName(fileName);
                        System.IO.StreamReader sr = System.IO.File.OpenText(fileDropList[i]);
                        sContents = sr.ReadToEnd();
                        sr.Close();

                        if (null != findTreeNode(fileName, tnParent))
                        {
                            if (bPrompt)
                            {
                                DialogResult dr = MessageBox.Show("iRule '" + fileName + "' already exists.  Do you wish to overwrite it?", "iRule Already Exists", MessageBoxButtons.YesNo);
                                if (DialogResult.Yes == dr)
                                {
                                    bCreateNewNode = false;
                                }
                                else
                                {
                                    // Create new node name based on given file name
                                    for (int j = 0; j < 1000; j++)
                                    {
                                        fileName = fileName + "_" + j.ToString();
                                        if (null == findTreeNode(fileName, tnParent))
                                        {
                                            break;
                                        }
                                    }
                                    bContinue = false;
                                }
                            }
                            else
                            {
                                bCreateNewNode = false;
                            }
                        }

                        TreeNode tn = null;

                        if (bContinue)
                        {
                            if (bCreateNewNode)
                            {
                                tn = new TreeNode();
                                tn.NodeFont = treeView_iRules.Font;
                                tn.Text = fileName + "*";
                                iRuleInfo iri = new iRuleInfo(fileName, sContents, true);
                                tn.Tag = iri;
                                int index = tnParent.Nodes.Add(tn);
                            }
                            else
                            {
                                tn = findTreeNode(fileName, tnParent);
                                tn.NodeFont = treeView_iRules.Font;
                                tn.Text = fileName + "*";
                                iRuleInfo iri = (iRuleInfo)tn.Tag;
                                if (null != iri)
                                {
                                    iri.rule_details = sContents;
                                    iri.modified = true;
                                }
                                if (tn == m_lastTreeViewNode)
                                {
                                    // make sure editor contents are up to date
                                    m_textEditor.Text = sContents;
                                }
                            }
                            treeView_iRules.SelectedNode = tn;
                            treeView_iRules.Select();
                        }
                    }
                    catch (Exception)
                    {
                    }

                }
            }
            this.Focus();
        }
        private void DoCopyOffline(TreeNode tn)
        {
            if (null != tn)
            {
                iRuleInfo iri = (iRuleInfo)tn.Tag;
                if (null != iri)
                {
                    bool bContinue = false;
                    bool bCreateNewNode = true;
                    bool bExisting = false;
                    TreeNode matchingNode = findTreeNode(iri.rule_name, m_treeNodeOffline);
                    if (null != matchingNode)
                    {
                        DialogResult dr = MessageBox.Show("iRule '" + iri.rule_name + "' already exists in the offline cache.  Would you like to overwrite it?");
                        if (DialogResult.OK == dr)
                        {
                            bCreateNewNode = false;
                        }
                        else
                        {
                            bContinue = false;
                        }
                    }
                    else
                    {
                        bContinue = true;
                    }
                    if (bContinue)
                    {
                        if (bCreateNewNode)
                        {
                            TreeNode tnNew = new TreeNode();
                            tnNew.NodeFont = treeView_iRules.Font;
                            tnNew.Text = iri.rule_name + "*";
                            iRuleInfo iriNew = new iRuleInfo(iri.rule_name, iri.rule_details, true);
                            tnNew.Tag = iriNew;
                            int index = m_treeNodeOffline.Nodes.Add(tnNew);
                            DoSaveOffline(tnNew);
                        }
                        else
                        {
                            iRuleInfo iriMatching = (iRuleInfo)matchingNode.Tag;
                            if (null != iriMatching)
                            {
                                iriMatching.rule_details = iri.rule_details;
                                iriMatching.modified = true;
                                DoSaveOffline(matchingNode);
                            }
                        }
                    }

                }
            }
        }