/// <summary>
    /// Generates tables
    /// </summary>
    private void GenerateTable()
    {
        tblData.Controls.Clear();

        Hashtable ht = data.ConvertToHashtable();

        TableHeaderRow th = new TableHeaderRow()
        {
            TableSection = TableRowSection.TableHeader
        };
        TableHeaderCell ha = new TableHeaderCell();
        TableHeaderCell hn = new TableHeaderCell();
        TableHeaderCell hv = new TableHeaderCell();

        th.CssClass = "unigrid-head";

        ha.Text     = GetString("unigrid.actions");
        ha.CssClass = "unigrid-actions-header";

        hn.Text  = GetString("xmleditor.propertyname");
        hn.Width = Unit.Pixel(180);
        hv.Text  = GetString("xmleditor.propertyvalue");
        hv.Width = Unit.Pixel(500);

        th.Cells.Add(ha);
        th.Cells.Add(hn);
        th.Cells.Add(hv);

        tblData.Rows.Add(th);

        ArrayList keys = new ArrayList(ht);

        keys.Sort(new CustomStringComparer());

        foreach (DictionaryEntry okey in keys)
        {
            String key   = ValidationHelper.GetString(okey.Key, String.Empty);
            String value = ValidationHelper.GetString(okey.Value, String.Empty);

            bool isInvalid = (key == INVALIDTOKEN);
            key = isInvalid ? invalidKey : key;

            if (value == String.Empty)
            {
                continue;
            }

            TableRow tr = new TableRow();

            // Actions
            TableCell tna = new TableCell();
            tna.CssClass = "unigrid-actions";

            var imgEdit = new CMSGridActionButton();
            imgEdit.OnClientClick = String.Format("displayEdit('{1}','{0}'); return false; ", key, ClientID);
            imgEdit.IconCssClass  = "icon-edit";
            imgEdit.IconStyle     = GridIconStyle.Allow;
            imgEdit.ID            = key + "_edit";
            imgEdit.ToolTip       = GetString("xmleditor.edititem");

            var imgOK = new CMSGridActionButton();
            imgOK.IconCssClass  = "icon-check";
            imgOK.IconStyle     = GridIconStyle.Allow;
            imgOK.OnClientClick = String.Format("approveCustomChanges('{0}','{1}');return false;", ClientID, key);
            imgOK.ID            = key + "_ok";
            imgOK.ToolTip       = GetString("xmleditor.approvechanges");

            var imgDelete = new CMSGridActionButton();
            imgDelete.OnClientClick = " if (confirm('" + GetString("xmleditor.deleteconfirm") + "')) {" + ControlsHelper.GetPostBackEventReference(tblData, "delete_" + key) + "} ;return false;";
            imgDelete.IconCssClass  = "icon-bin";
            imgDelete.IconStyle     = GridIconStyle.Critical;
            imgDelete.ID            = key + "_del";
            imgDelete.ToolTip       = GetString("xmleditor.deleteitem");

            var imgUndo = new CMSGridActionButton();
            imgUndo.OnClientClick = String.Format("if (confirm('" + GetString("xmleditor.confirmcancel") + "')) undoCustomChanges('{0}','{1}'); return false;", ClientID, key);
            imgUndo.IconCssClass  = "icon-arrow-crooked-left";
            imgUndo.ID            = key + "_undo";
            imgUndo.ToolTip       = GetString("xmleditor.undochanges");

            tna.Controls.Add(imgEdit);
            tna.Controls.Add(imgOK);
            tna.Controls.Add(imgDelete);
            tna.Controls.Add(imgUndo);

            value = MacroSecurityProcessor.RemoveSecurityParameters(value, false, null);

            // Labels
            Label lblName = new Label();
            lblName.ID   = "sk" + key;
            lblName.Text = key;

            Label lblValue = new Label();
            lblValue.ID   = "sv" + key;
            lblValue.Text = value;

            // Textboxes
            CMSTextBox txtName = new CMSTextBox();
            txtName.Text     = key;
            txtName.ID       = "tk" + key;
            txtName.CssClass = "XmlEditorTextbox";

            CMSTextBox txtValue = new CMSTextBox();
            txtValue.Text     = value;
            txtValue.ID       = "tv" + key;
            txtValue.CssClass = "XmlEditorTextbox";
            txtValue.Width    = Unit.Pixel(490);

            labels.Add(lblName);
            labels.Add(lblValue);

            textboxes.Add(txtName);
            textboxes.Add(txtValue);

            TableCell tcn = new TableCell();
            tcn.Controls.Add(lblName);
            tcn.Controls.Add(txtName);

            TableCell tcv = new TableCell();
            tcv.Controls.Add(lblValue);
            tcv.Controls.Add(txtValue);

            tr.Cells.Add(tna);
            tr.Cells.Add(tcn);
            tr.Cells.Add(tcv);

            tblData.Rows.Add(tr);

            lblValue.CssClass = String.Empty;
            lblName.CssClass  = "CustomEditorKeyClass";

            if (isInvalid)
            {
                imgDelete.AddCssClass("hidden");
                imgEdit.AddCssClass("hidden");

                lblName.AddCssClass("hidden");
                lblValue.AddCssClass("hidden");

                RegisterEnableScript(false);
            }
            else
            {
                imgOK.AddCssClass("hidden");
                imgUndo.AddCssClass("hidden");

                txtName.CssClass  += " hidden";
                txtValue.CssClass += " hidden";
            }
        }
    }