/// <summary>
        /// Save all comments to database (direct)
        /// </summary>
        /// <param name="companyId">companyId</param>        
        public void Save(int companyId)
        {
            FlatSectionJlTDS flatSectionJlHistoryDetailsChanges = (FlatSectionJlTDS)Data.GetChanges();

            if (flatSectionJlHistoryDetailsChanges.FlatSectionJlHistoryDetails.Rows.Count > 0)
            {
                FlatSectionJlHistoryDetailsGateway flatSectionJlHistoryDetailsGateway = new FlatSectionJlHistoryDetailsGateway(flatSectionJlHistoryDetailsChanges);

                foreach (FlatSectionJlTDS.FlatSectionJlHistoryDetailsRow row in (FlatSectionJlTDS.FlatSectionJlHistoryDetailsDataTable)flatSectionJlHistoryDetailsChanges.FlatSectionJlHistoryDetails)
                {
                    // Insert new comments
                    if ((!row.Deleted) && (!row.InDatabase))
                    {
                        WorkHistory workHistory = new WorkHistory(null);
                        int? libraryFilesId = null; if (!row.IsLIBRARY_FILES_IDNull()) libraryFilesId = row.LIBRARY_FILES_ID;
                        string workType = ""; if (!row.IsWorkTypeNull()) workType = row.WorkType;

                        workHistory.InsertDirect(row.WorkID, row.RefID, row.Type, row.Subject, row.UserID, row.DateTime_, row.History, libraryFilesId, row.Deleted, row.COMPANY_ID, workType);
                    }

                    // Update comments
                    if ((!row.Deleted) && (row.InDatabase))
                    {
                        int workId = row.WorkID;
                        int refId = row.RefID;
                        bool originalDeleted = false;
                        int originalCompanyId = companyId;

                        // original values
                        string originalType = flatSectionJlHistoryDetailsGateway.GetTypeOriginal(workId, refId);
                        string originalSubject = flatSectionJlHistoryDetailsGateway.GetSubjectOriginal(workId, refId);
                        int originalUserId = flatSectionJlHistoryDetailsGateway.GetUserIdOriginal(workId, refId);
                        DateTime? originalDateTime = null; if (flatSectionJlHistoryDetailsGateway.GetDateTime_Original(workId, refId) != null) originalDateTime = flatSectionJlHistoryDetailsGateway.GetDateTime_Original(workId, refId);
                        string originalComment = flatSectionJlHistoryDetailsGateway.GetCommentOriginal(workId, refId);
                        int? originalLibraryFilesId = null; if (flatSectionJlHistoryDetailsGateway.GetLIBRARY_FILES_IDOriginal(workId, refId) != null) originalLibraryFilesId = flatSectionJlHistoryDetailsGateway.GetLIBRARY_FILES_IDOriginal(workId, refId);
                        string originalWorkType = flatSectionJlHistoryDetailsGateway.GetWorkTypeOriginal(workId, refId);

                        // new values
                        string newSubject = flatSectionJlHistoryDetailsGateway.GetSubject(workId, refId);
                        string newComment = flatSectionJlHistoryDetailsGateway.GetComment(workId, refId);
                        int? newLibraryFilesId = null; if (flatSectionJlHistoryDetailsGateway.GetLIBRARY_FILES_IDOriginal(workId, refId) != null) originalLibraryFilesId = flatSectionJlHistoryDetailsGateway.GetLIBRARY_FILES_ID(workId, refId);

                        WorkHistory workHistory = new WorkHistory(null);
                        workHistory.UpdateDirect(workId, refId, originalType, originalSubject, originalUserId, originalDateTime, originalComment, originalLibraryFilesId, originalDeleted, originalCompanyId, originalWorkType, workId, refId, originalType, newSubject, originalUserId, originalDateTime, newComment, newLibraryFilesId, originalDeleted, originalCompanyId, originalWorkType);
                    }

                    // Deleted comments
                    if ((row.Deleted) && (row.InDatabase))
                    {
                        WorkHistory workHistory = new WorkHistory(null);
                        workHistory.DeleteDirect(row.WorkID, row.RefID, row.COMPANY_ID);
                    }
                }
            }
        }
        // ////////////////////////////////////////////////////////////////////////
        // EVENTS
        //
        protected void Page_Load(object sender, EventArgs e)
        {
            // Register client scripts
            this.RegisterClientScripts();

            if (!IsPostBack)
            {
                // Security check
                if (!(Convert.ToBoolean(Session["sgLFS_CWP_JUNCTIONLINING_VIEW"]) && Convert.ToBoolean(Session["sgLFS_CWP_JUNCTIONLINING_EDIT"])))
                {
                    Response.Redirect("./../../error_page.aspx?error=" + "You are not authorized to view this page. Contact your system administrator.");
                }

                // Validate query string
                if (((string)Request.QueryString["source_page"] == null) || ((string)Request.QueryString["client_id"] == null) || ((string)Request.QueryString["project_id"] == null) || ((string)Request.QueryString["row_asset_id"] == null) || ((string)Request.QueryString["row_focus"] == null) || ((string)Request.QueryString["work_type"] == null))
                {
                    Response.Redirect("./../../error_page.aspx?error=" + "Invalid query string in jl_comments.aspx");
                }

                // Tag Page
                hdfCompanyId.Value = Session["companyID"].ToString();
                hdfCurrentProjectId.Value = Request.QueryString["project_id"].ToString();
                hdfCurrentClientId.Value = Request.QueryString["client_id"].ToString();
                hdfLoginId.Value = Convert.ToInt32(Session["loginID"]).ToString();
                hdfAssetId.Value = Convert.ToString(Request.QueryString["row_asset_id"]);
                hdfAdminPermission.Value = Convert.ToBoolean(Session["sgLFS_CWP_JUNCTIONLINING_ADMIN"]).ToString();
                hdfWorkType.Value = Request.QueryString["work_type"].ToString();
                hdfSection_.Value = Request.QueryString["section_"].ToString();
                hdfUpdate.Value = "yes";

                // ... Names for UserList
                string workType = hdfWorkType.Value.Trim();
                int companyId = Int32.Parse(hdfCompanyId.Value);

                LoginGateway loginGateway = new LoginGateway();
                loginGateway.LoadByLoginId(Convert.ToInt32(hdfLoginId.Value), companyId);
                hdfCreatedBy.Value = loginGateway.GetLastName(Convert.ToInt32(hdfLoginId.Value), companyId) + " " + loginGateway.GetFirstName(Convert.ToInt32(hdfLoginId.Value), companyId);
                hdfCreationDateTime.Value = DateTime.Now.ToString();

                // Prepare initial data
                Session.Remove("flatSectionJlCommentDetailsDummy");

                // If coming from
                // ... flat_section_jl_summary.aspx or flat_section_jl_edit.aspx
                if (Request.QueryString["source_page"] == "flat_section_jl_summary.aspx" || Request.QueryString["source_page"] == "flat_section_jl_edit.aspx")
                {
                    StoreNavigatorState();
                    ViewState["update"] = Request.QueryString["update"];
                    Session["rowFocus"] = Convert.ToInt32(Request.QueryString["row_focus"].ToString());

                    // ... Load comments to edit
                    flatSectionJlTDS = (FlatSectionJlTDS)Session["flatSectionJlTDS"];
                    jlNavigatorTDS = (JlNavigatorTDS)Session["jlNavigatorTDS"];

                    // Get workId
                    int assetId = Int32.Parse(hdfAssetId.Value.Trim());
                    int currentProjectId = Int32.Parse(hdfCurrentProjectId.Value.Trim());
                    int jlWorkId = 0;
                    int raWorkId = 0;
                    int flWorkId = 0;

                    WorkGateway searchWorkGateway = new WorkGateway();
                    searchWorkGateway.LoadByProjectIdAssetIdWorkType(currentProjectId, assetId, "Junction Lining Lateral", companyId);

                    // ... If the project has jl works
                    if (searchWorkGateway.Table.Rows.Count > 0)
                    {
                        jlWorkId = searchWorkGateway.GetWorkId(assetId, "Junction Lining Lateral", currentProjectId);

                        // ... ...Tag Page
                        hdfWorkId.Value = jlWorkId.ToString().Trim();

                        // ... ...Get ra work id for comments
                        int section_ = Int32.Parse(hdfSection_.Value) ;
                        WorkGateway workGatewayRAFL = new WorkGateway();

                        // ... ...Get fl work id for comments
                        workGatewayRAFL.LoadByProjectIdAssetIdWorkType(currentProjectId, section_, "Full Length Lining", companyId);
                        if (workGatewayRAFL.Table.Rows.Count > 0)
                        {
                            flWorkId = workGatewayRAFL.GetWorkId(section_, "Full Length Lining", currentProjectId);
                        }

                        workGatewayRAFL.LoadByProjectIdAssetIdWorkType(currentProjectId, section_, "Rehab Assessment", companyId);
                        if (workGatewayRAFL.Table.Rows.Count > 0)
                        {
                            raWorkId = workGatewayRAFL.GetWorkId(section_, "Rehab Assessment", currentProjectId);
                        }

                        // ... ...Get comments
                        FlatSectionJlCommentDetailsGateway flatSectionJlCommentDetailsGateway = new FlatSectionJlCommentDetailsGateway(flatSectionJlTDS);
                        flatSectionJlCommentDetailsGateway.LoadAllByJlWorkIdRaWorkIdFlWorkId(jlWorkId, raWorkId, flWorkId, companyId);

                        FlatSectionJlCommentDetails flatSectionJlCommentDetails = new FlatSectionJlCommentDetails(flatSectionJlCommentDetailsGateway.Data);
                        flatSectionJlCommentDetails.UpdateForProcess();

                        // ... ...Get history
                        FlatSectionJlHistoryDetailsGateway flatSectionJlHistoryDetailsGateway = new FlatSectionJlHistoryDetailsGateway(flatSectionJlTDS);
                        flatSectionJlHistoryDetailsGateway.LoadAllByJlWorkIdRaWorkIdFlWorkId(jlWorkId, raWorkId, flWorkId, companyId);
                    }

                    // ... Store datasets
                    Session["flatSectionJlTDS"] = flatSectionJlTDS;
                    Session["jlNavigatorTDS"] = jlNavigatorTDS;
                    Session["flatSectionJlCommentDetails"] = flatSectionJlTDS.FlatSectionJlCommentDetails;
                }
            }
            else
            {
                // Restore datasets
                flatSectionJlTDS = (FlatSectionJlTDS)Session["flatSectionJlTDS"];
                jlNavigatorTDS = (JlNavigatorTDS)Session["jlNavigatorTDS"];
                flatSectionJlCommentDetails = flatSectionJlTDS.FlatSectionJlCommentDetails;

                // Store
                Session["flatSectionJlCommentDetails"] = flatSectionJlTDS.FlatSectionJlCommentDetails;
            }
        }