/// <summary>
        /// Add a node to the TreeView
        /// Node Tag points to all the information related to theat node
        /// in a class of type 'clsDatasetTreeNode'
        /// </summary>
        /// <param name="mdataNode"></param>
        private void AddDataNode(clsDatasetTreeNode mdataNode)
        {
            TreeNode tn;
            if ((mtabControlData.Controls.Count == 0) &&
                (mhtDatasets.ContainsKey("Expressions") ||
                 mhtDatasets.ContainsKey("Protein Info") ||
                 mhtDatasets.ContainsKey("Factors")))
            {
                #region Add Controls on tab page
                var dataGridTab = new ucDataGridView();
                this.ctltabPage = new TabPage();
                this.mtabControlData.Controls.Add(this.ctltabPage);
                this.ctltabPage.Name = "ctltabPageData";
                this.ctltabPage.Controls.Add(dataGridTab);
                dataGridTab.Dock = System.Windows.Forms.DockStyle.Fill;
                #endregion
            }

            if (mdataNode.mDTable == null)
            {
                return;
            }

            //mdataNode.mDTable.rea
            if ((tn = GetNode(mdataNode.mstrDataText)) == null)
            {
                this.ctltabPage.TabIndex = 0;
                this.ctltabPage.Text = mdataNode.mstrDataText;
                ((ucDataGridView)this.ctltabPage.Controls[0]).SetDataSource = mdataNode.mDTable;

                if (mdataNode.mblAddDGridCtxtMnu)
                    ((ucDataGridView)this.ctltabPage.Controls[0]).CxMenu = mCntxtMnuGrid;
                if (mdataNode.mblAddTVCtxtMnu)
                    mdataNode.mTNode.ContextMenuStrip = mContextMenuTreeV;

                if (mdataNode.mstrParentNode.Equals("DAnTE"))
                    ctltreeView.Nodes[0].Nodes.Add(mdataNode.mTNode);
                else
                {
                    var mtnParent = (mhtDatasets[mdataNode.mstrParentNode]).mTNode;
                    mtnParent.Nodes.Add(mdataNode.mTNode);
                }
                ctltreeView.ExpandAll();
                ctltreeView.SelectedNode = mdataNode.mTNode;
                this.statusBarPanelMsg.Text = mdataNode.mstrMessage;
                this.statusBarPanelRowNum.Text = mdataNode.mDTable.Rows.Count + " Rows/" +
                                                 mdataNode.mDTable.Columns.Count + " Columns.";
                mdataNode.mTNode.Tag = mdataNode;
            }
            else
            {
                tn.Tag = mdataNode;
                ctltreeView.SelectedNode = tn;
                NodeSelect(tn);
            }
        }
        private void SaveTableWithProteinIDs(clsDatasetTreeNode selectedTable, FileInfo outputFile)
        {
            // Write out the current dataset, but with the the protein info included
            var currentDataset = mhtDatasets[selectedTable.mstrDataText];
            var proteinDataset = mhtDatasets["Protein Info"];

            // Store the proteins in a dictionary so that we can quickly lookup the info
            // Keys are row_id, values are Lists of protein names
            var proteinList = new Dictionary<string, List<string>>();

            foreach (DataRow row in proteinDataset.mDTable.Rows)
            {
                // Column 0 is Row_ID
                // Column 1 is ProteinID

                var rowID = row[0].ToString();
                var proteinID = row[1].ToString();

                if (string.IsNullOrWhiteSpace(rowID) || string.IsNullOrWhiteSpace(proteinID))
                    continue;

                List<string> proteinsForRow;
                if (proteinList.TryGetValue(rowID, out proteinsForRow))
                {
                    proteinsForRow.Add(proteinID);
                }
                else
                {
                    proteinsForRow = new List<string>
                        {
                            proteinID
                        };
                    proteinList.Add(rowID, proteinsForRow);
                }
            }

            const bool quoteAll = false;
            var tabDelimited = outputFile.Extension.ToLower() == ".txt";

            using (var writer = new StreamWriter(new FileStream(outputFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read)))
            {

                var columnCount = currentDataset.mDTable.Columns.Count;
                var rowData = new List<string>(columnCount);

                for (var i = 0; i < columnCount; i++)
                {
                    rowData.Add(currentDataset.mDTable.Columns[i].Caption);

                    // Add the ProteinID just after the first column
                    if (i == 0)
                        rowData.Add("ProteinID");
                }

                CsvWriter.WriteRow(writer, rowData, quoteAll, tabDelimited);

                foreach (DataRow row in currentDataset.mDTable.Rows)
                {
                    var rowID = row[0].ToString();
                    List<string> proteinsForRow;
                    if (!proteinList.TryGetValue(rowID, out proteinsForRow))
                    {
                        proteinsForRow = new List<string>
                            {
                                "Undefined"
                            };
                    }

                    foreach (var proteinID in proteinsForRow)
                    {
                        rowData.Clear();

                        for (var j = 0; j < columnCount; j++)
                        {
                            var itemText = string.Empty;

                            if (row[j] != null)
                            {
                                itemText = row[j].ToString();
                            }

                            rowData.Add(itemText);

                            // Add the ProteinID just after the first column
                            if (j == 0)
                                rowData.Add(proteinID);
                        }
                        CsvWriter.WriteRow(writer, rowData, quoteAll, tabDelimited);
                    }

                }

                this.statusBarPanelMsg.Text = "File saved successfully.";
            }
        }
        private void AddDataset2HashTable(DataTable mDT)
        {
            var mstrRdataset = mDT.TableName;
            var mclsDataset = new clsDatasetTreeNode
            {
                mDTable = mDT
            };

            switch (mstrRdataset)
            {
                case "Eset":
                    #region Eset
                    mclsDataset.mTNode = new TreeNode("Expressions", 1, 2);
                    mclsDataset.mstrDataText = "Expressions";
                    mclsDataset.mstrMessage = "Expression values selected.";
                    mclsDataset.mstrRdatasetName = "Eset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Expressions"))
                        mhtDatasets["Expressions"] = mclsDataset;
                    else
                        mhtDatasets.Add("Expressions", mclsDataset);

                    if (!mhtDatasets.ContainsKey("Factors"))
                        DatasetFactorInfo(mDT, false);
                    break;
                    #endregion
                case "ProtInfo":
                    #region ProtInfo
                    mclsDataset.mTNode = new TreeNode("Protein Info", 3, 4);
                    mclsDataset.mstrDataText = "Protein Info";
                    mclsDataset.mstrMessage = "Protein Info selected.";
                    mclsDataset.mstrRdatasetName = "ProtInfo";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Protein Info"))
                        mhtDatasets["Protein Info"] = mclsDataset;
                    else
                        mhtDatasets.Add("Protein Info", mclsDataset);
                    break;
                    #endregion
                case "factors":
                    #region Factors
                    mclsDataset.mTNode = new TreeNode("Factors", 3, 4);
                    mclsDataset.mstrDataText = "Factors";
                    mclsDataset.mstrMessage = "Factors selected.";
                    mclsDataset.mstrRdatasetName = "factors";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Factors"))
                        mhtDatasets["Factors"] = mclsDataset;
                    else
                        mhtDatasets.Add("Factors", mclsDataset);
                    marrDatasetInfo.Clear();
                    DatasetFactorInfo(mDT, true);
                    break;
                    #endregion
                case "logEset":
                    #region logEset
                    mclsDataset.mTNode = new TreeNode("Log Expressions", 1, 2);
                    mclsDataset.mstrDataText = "Log Expressions";
                    mclsDataset.mstrMessage = "Log Expressions selected.";
                    mclsDataset.mstrRdatasetName = "logEset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Log Expressions"))
                        mhtDatasets["Log Expressions"] = mclsDataset;
                    else
                        mhtDatasets.Add("Log Expressions", mclsDataset);
                    break;
                    #endregion
                case "loessData":
                    #region loessData
                    mclsDataset.mTNode = new TreeNode("LOESS Data", 1, 2);
                    mclsDataset.mstrDataText = "LOESS Data";
                    mclsDataset.mstrMessage = "LOESS Data selected.";
                    mclsDataset.mstrRdatasetName = "loessData";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("LOESS Data"))
                        mhtDatasets["LOESS Data"] = mclsDataset;
                    else
                        mhtDatasets.Add("LOESS Data", mclsDataset);
                    break;
                    #endregion
                case "quaNormEset":
                    #region quaNormEset
                    mclsDataset.mTNode = new TreeNode("Quantile Normalized", 1, 2);
                    mclsDataset.mstrDataText = "Quantile Normalized";
                    mclsDataset.mstrMessage = "Quantile normalized data selected.";
                    mclsDataset.mstrRdatasetName = "quaNormEset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Quantile Normalized"))
                        mhtDatasets["Quantile Normalized"] = mclsDataset;
                    else
                        mhtDatasets.Add("Quantile Normalized", mclsDataset);
                    break;
                    #endregion
                case "meanCEset":
                    #region MeanCEset
                    mclsDataset.mTNode = new TreeNode("Mean Centered", 1, 2);
                    mclsDataset.mstrDataText = "Mean Centered";
                    mclsDataset.mstrMessage = "Mean centered data selected.";
                    mclsDataset.mstrRdatasetName = "meanCEset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Mean Centered"))
                        mhtDatasets["Mean Centered"] = mclsDataset;
                    else
                        mhtDatasets.Add("Mean Centered", mclsDataset);
                    break;
                    #endregion
                case "medianCEset":
                    #region MedianCEset
                    mclsDataset.mTNode = new TreeNode("Median Centered", 1, 2);
                    mclsDataset.mstrDataText = "Median Centered";
                    mclsDataset.mstrMessage = "Median centered data selected.";
                    mclsDataset.mstrRdatasetName = "medianCEset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Median Centered"))
                        mhtDatasets["Median Centered"] = mclsDataset;
                    else
                        mhtDatasets.Add("Median Centered", mclsDataset);
                    break;
                    #endregion
                case "madEset":
                    #region madEset
                    mclsDataset.mTNode = new TreeNode("MAD Adjusted", 1, 2);
                    mclsDataset.mstrDataText = "MAD Adjusted";
                    mclsDataset.mstrMessage = "MAD Adjusted data selected.";
                    mclsDataset.mstrRdatasetName = "madEset";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("MAD Adjusted"))
                        mhtDatasets["MAD Adjusted"] = mclsDataset;
                    else
                        mhtDatasets.Add("MAD Adjusted", mclsDataset);
                    break;
                    #endregion
                case "linregData":
                    #region linregData
                    mclsDataset.mTNode = new TreeNode("Linear Regressed", 1, 2);
                    mclsDataset.mstrDataText = "Linear Regressed";
                    mclsDataset.mstrMessage = "Linear Regressed Data selected.";
                    mclsDataset.mstrRdatasetName = "linregData";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Linear Regressed"))
                        mhtDatasets["Linear Regressed"] = mclsDataset;
                    else
                        mhtDatasets.Add("Linear Regressed", mclsDataset);
                    break;
                    #endregion
                case "imputedData":
                    #region imputedData
                    mclsDataset.mTNode = new TreeNode("Imputed Data", 1, 2);
                    mclsDataset.mstrDataText = "Imputed Data";
                    mclsDataset.mstrMessage = "Imputed Data selected.";
                    mclsDataset.mstrRdatasetName = "imputedData";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    if (mhtDatasets.ContainsKey("Imputed Data"))
                        mhtDatasets["Imputed Data"] = mclsDataset;
                    else
                        mhtDatasets.Add("Imputed Data", mclsDataset);
                    break;
                    #endregion
                case "mergedData":
                    #region mergedData
                    mclsDataset.mTNode = new TreeNode("Merged Data", 1, 2);
                    mclsDataset.mstrDataText = "Merged Data";
                    mclsDataset.mstrMessage = "Merged Data selected.";
                    mclsDataset.mstrRdatasetName = "mergedData";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Merged Data"))
                        mhtDatasets["Merged Data"] = mclsDataset;
                    else
                        mhtDatasets.Add("Merged Data", mclsDataset);
                    break;
                    #endregion
                case "pData11":
                    #region pData11 (RRollup)
                    mclsDataset.mTNode = new TreeNode("RRollup", 1, 2);
                    mclsDataset.mstrDataText = "RRollup";
                    mclsDataset.mstrMessage = "RRollup selected.";
                    mclsDataset.mstrRdatasetName = "pData11";
                    mclsDataset.mstrRProtDatasetName = @"pScaled1"",""pData1";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("RRollup"))
                        mhtDatasets["RRollup"] = mclsDataset;
                    else
                        mhtDatasets.Add("RRollup", mclsDataset);
                    break;
                    #endregion
                case "sData1":
                    #region sData1 (RRollup)
                    mclsDataset.mTNode = new TreeNode("ScaledData", 1, 2);
                    mclsDataset.mstrDataText = "ScaledData";
                    mclsDataset.mstrMessage = "Scaled data selected.";
                    mclsDataset.mstrRdatasetName = "sData1";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    mclsDataset.mstrParentNode = "RRollup";
                    if (mhtDatasets.ContainsKey("ScaledData"))
                        mhtDatasets["ScaledData"] = mclsDataset;
                    else
                        mhtDatasets.Add("ScaledData", mclsDataset);
                    break;
                    #endregion
                case "orData1":
                    #region orData1 (RRollup)
                    mclsDataset.mTNode = new TreeNode("OutliersRemoved", 1, 2);
                    mclsDataset.mstrDataText = "OutliersRemoved";
                    mclsDataset.mstrMessage = "Outliers removed data selected.";
                    mclsDataset.mstrRdatasetName = "orData1";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    mclsDataset.mstrParentNode = "RRollup";
                    if (mhtDatasets.ContainsKey("OutliersRemoved"))
                        mhtDatasets["OutliersRemoved"] = mclsDataset;
                    else
                        mhtDatasets.Add("OutliersRemoved", mclsDataset);
                    break;
                    #endregion
                case "pData22":
                    #region pData2 (ZRollup)
                    mclsDataset.mTNode = new TreeNode("ZRollup", 1, 2);
                    mclsDataset.mstrDataText = "ZRollup";
                    mclsDataset.mstrMessage = "ZRollup selected.";
                    mclsDataset.mstrRdatasetName = "pData22";
                    mclsDataset.mstrRProtDatasetName = @"pScaled2"",""pData2";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("ZRollup"))
                        mhtDatasets["ZRollup"] = mclsDataset;
                    else
                        mhtDatasets.Add("ZRollup", mclsDataset);
                    break;
                    #endregion
                case "qrollupP1":
                    #region QRollupP1
                    mclsDataset.mTNode = new TreeNode("QRollup", 1, 2);
                    mclsDataset.mstrDataText = "QRollup";
                    mclsDataset.mstrMessage = "QRollup selected.";
                    mclsDataset.mstrRdatasetName = "qrollupP1";
                    mclsDataset.mstrRProtDatasetName = "qrollupP";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("QRollup"))
                        mhtDatasets["QRollup"] = mclsDataset;
                    else
                        mhtDatasets.Add("QRollup", mclsDataset);
                    break;
                    #endregion
                case "PCAweights":
                    #region PCA weights
                    mclsDataset.mTNode = new TreeNode("PCA Weights", 3, 4);
                    mclsDataset.mstrDataText = "PCA Weights";
                    mclsDataset.mstrMessage = "PCA Weights selected.";
                    mclsDataset.mstrRdatasetName = "PCAweights";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("PCA Weights"))
                        mhtDatasets["PCA Weights"] = mclsDataset;
                    else
                        mhtDatasets.Add("PCA Weights", mclsDataset);
                    break;
                    #endregion
                case "PLSweights":
                    #region PCA weights
                    mclsDataset.mTNode = new TreeNode("PLS Weights", 3, 4);
                    mclsDataset.mstrDataText = "PLS Weights";
                    mclsDataset.mstrMessage = "PLS Weights selected.";
                    mclsDataset.mstrRdatasetName = "PLSweights";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("PLS Weights"))
                        mhtDatasets["PLS Weights"] = mclsDataset;
                    else
                        mhtDatasets.Add("PLS Weights", mclsDataset);
                    break;
                    #endregion
                case "clusterResults":
                    #region PCA weights
                    mclsDataset.mTNode = new TreeNode("Heatmap Clusters", 3, 4);
                    mclsDataset.mstrDataText = "Heatmap Clusters";
                    mclsDataset.mstrMessage = "Heatmap Clusters selected.";
                    mclsDataset.mstrRdatasetName = "clusterResults";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Heatmap Clusters"))
                        mhtDatasets["Heatmap Clusters"] = mclsDataset;
                    else
                        mhtDatasets.Add("Heatmap Clusters", mclsDataset);
                    break;
                    #endregion
                case "pvalues":
                    #region p-values
                    mclsDataset.mTNode = new TreeNode("p-Values", 3, 4);
                    mclsDataset.mstrDataText = "p-Values";
                    mclsDataset.mstrMessage = "p-Values selected.";
                    mclsDataset.mstrRdatasetName = "pvalues";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("p-Values"))
                        mhtDatasets["p-Values"] = mclsDataset;
                    else
                        mhtDatasets.Add("p-Values", mclsDataset);
                    break;
                    #endregion
                case "yimputed":
                    #region yimputed
                    mclsDataset.mTNode = new TreeNode("Imputed Values", 1, 2);
                    mclsDataset.mstrDataText = "Imputed Values";
                    mclsDataset.mstrMessage = "Imputed Values selected.";
                    mclsDataset.mstrRdatasetName = "yimputed";
                    mclsDataset.mblAddDGridCtxtMnu = true;
                    mclsDataset.mblAddTVCtxtMnu = true;
                    mclsDataset.mblIsNumeric = true;
                    mclsDataset.mblIsPlottable = true;
                    mclsDataset.mblRollupPossible = true;
                    if (mhtDatasets.ContainsKey("Imputed Values"))
                        mhtDatasets["Imputed Values"] = mclsDataset;
                    else
                        mhtDatasets.Add("Imputed Values", mclsDataset);
                    break;
                    #endregion
                case "notused":
                    #region Unused data for ANOVA
                    mclsDataset.mTNode = new TreeNode("Unused Data", 3, 4);
                    mclsDataset.mstrDataText = "Unused Data";
                    mclsDataset.mstrMessage = "Unused Data selected.";
                    mclsDataset.mstrRdatasetName = "notused";
                    mclsDataset.mstrParentNode = "p-Values";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = true;
                    mclsDataset.mblIsPlottable = true;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Unused Data"))
                        mhtDatasets["Unused Data"] = mclsDataset;
                    else
                        mhtDatasets.Add("Unused Data", mclsDataset);
                    break;
                    #endregion
                case "foldChanges":
                    #region Fold Changes
                    mclsDataset.mTNode = new TreeNode("Fold Changes", 3, 4);
                    mclsDataset.mstrDataText = "Fold Changes";
                    mclsDataset.mstrMessage = "Fold Changes selected.";
                    mclsDataset.mstrRdatasetName = "foldChanges";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Fold Changes"))
                        mhtDatasets["Fold Changes"] = mclsDataset;
                    else
                        mhtDatasets.Add("Fold Changes", mclsDataset);
                    break;
                    #endregion
                case "patternData":
                    #region Pattern Search
                    mclsDataset.mTNode = new TreeNode("Pattern Corr", 3, 4);
                    mclsDataset.mstrDataText = "Pattern Corr";
                    mclsDataset.mstrMessage = "Pattern Correlations selected.";
                    mclsDataset.mstrRdatasetName = "patternData";
                    mclsDataset.mblAddDGridCtxtMnu = false;
                    mclsDataset.mblAddTVCtxtMnu = false;
                    mclsDataset.mblIsNumeric = false;
                    mclsDataset.mblIsPlottable = false;
                    mclsDataset.mblRollupPossible = false;
                    if (mhtDatasets.ContainsKey("Pattern Corr"))
                        mhtDatasets["Pattern Corr"] = mclsDataset;
                    else
                        mhtDatasets.Add("Pattern Corr", mclsDataset);
                    break;
                    #endregion
                default:
                    #region All other tables (filteredData)
                    if (mstrRdataset.Contains("filteredData"))
                    {
                        var setNum = mstrRdataset.Substring(12);
                        var nodeTxt = "Filtered Data" + setNum;
                        mclsDataset.mTNode = new TreeNode(nodeTxt, 1, 2);
                        mclsDataset.mstrDataText = nodeTxt;
                        mclsDataset.mstrMessage = "Filtered Data selected.";
                        mclsDataset.mstrRdatasetName = mstrRdataset;
                        mclsDataset.mblAddDGridCtxtMnu = true;
                        mclsDataset.mblAddTVCtxtMnu = false;
                        if (mhtDatasets.ContainsKey(nodeTxt))
                            mhtDatasets[nodeTxt] = mclsDataset;
                        else
                            mhtDatasets.Add(nodeTxt, mclsDataset);
                    }
                    break;
                    #endregion
            }
        }
        private bool ValidateNodeIsSelected(clsDatasetTreeNode selectedNode)
        {
            if (selectedNode == null)
            {
                MessageBox.Show("Data not loaded (or data table not selected)", "Nothing to do", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            return true;
        }
        private bool ValidateIsPlottable(clsDatasetTreeNode mclsSelected, int minimumColCount = 1)
        {
            if (!mclsSelected.mblIsPlottable)
            {
                MessageBox.Show("Table '" + mclsSelected.mstrDataText + "' does not contain data that can be plotted.  Please select a different table from the list", "Invalid table");
                return false;
            }

            if (minimumColCount > 1 && mclsSelected.mDTable.Columns.Count < minimumColCount)
            {
                MessageBox.Show("Table '" + mclsSelected.mstrDataText + "' cannot be plotted; it must have at least " + minimumColCount + " columns of data", "Not enough columns");
                return false;
            }
            return true;
        }
        private bool ValidateDataMatrixTableSelected(clsDatasetTreeNode mclsSelected, bool checkColumnCount = false)
        {
            if (mclsSelected == null)
            {
                MessageBox.Show("Please select a numeric data table from the list", "Invalid table");
                return false;
            }

            if (mclsSelected.mDTable == null)
            {
                MessageBox.Show("Please select a numeric data table from the list", "Invalid table");
                return false;
            }

            if (!mclsSelected.mblIsNumeric)
            {
                MessageBox.Show("Table '" + mclsSelected.mstrDataText + "' does not contain a matrix of numeric data.  Please select a different table from the list", "Invalid table");
                return false;
            }

            if (checkColumnCount)
            {
                var numCols = mclsSelected.mDTable.Columns.Count - 1;
                if (numCols <= 0)
                {
                    MessageBox.Show("Table '" + mclsSelected.mstrDataText + "' must have at least 2 columns of data", "Invalid table");
                    return false;
                }
            }
            return true;
        }