/// <summary>
        /// Asynchronous After event that occurs after an existing item is changed, for example, when the user changes data in one or more fields.
        /// </summary>
        /// <param name="properties">An <see cref="T:Microsoft.SharePoint.SPItemEventProperties" /> object that represents properties of the event handler.</param>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            try
            {
                base.ItemUpdated(properties);
                object levelbefore         = properties.BeforeProperties["vti_level"];
                object levelafter          = properties.AfterProperties["vti_level"];
                object doclibmodstatbefore = properties.BeforeProperties["vti_doclibmodstat"];
                object doclibmodstatafter  = properties.AfterProperties["vti_doclibmodstat"];

                if (levelbefore != null && levelafter != null)
                {
                    int  levelBefore, levelAfter, doclibmodstatBefore = -1, doclibmodstatAfter = -1;
                    bool levelBeforeParsed, levelAfterParsed, doclibmodstatBeforeParsed = false, doclibmodstatAfterParsed = false;

                    levelBeforeParsed = int.TryParse(levelbefore.ToString(), out levelBefore);
                    levelAfterParsed  = int.TryParse(levelafter.ToString(), out levelAfter);

                    if (doclibmodstatbefore != null)
                    {
                        doclibmodstatBeforeParsed = int.TryParse(doclibmodstatbefore.ToString(), out doclibmodstatBefore);
                    }

                    if (doclibmodstatafter != null)
                    {
                        doclibmodstatAfterParsed = int.TryParse(doclibmodstatafter.ToString(), out doclibmodstatAfter);
                    }

                    if (levelBeforeParsed && levelAfterParsed && doclibmodstatAfterParsed && doclibmodstatBeforeParsed)
                    {
                        if (string.IsNullOrEmpty(properties.ListItem.ModerationInformation.Comment) || !properties.ListItem.ModerationInformation.Comment.Equals(ListConstants.ApprovalWorkflowModerationComment))
                        {
                            // Check to cancel workflow on Direct Approval/Rejection.
                            // Must have levelbefore =2, levelAfter = 2, doclibmodstatbefore = 2 and (doclibmodstatafter = 0 or doclibmodstatafter = 1)
                            if (levelBefore == 2 && levelAfter == 2 && doclibmodstatBefore == 2 && (doclibmodstatAfter == 0 || doclibmodstatAfter == 1))
                            {
                                WorkflowHelper2013.CancelApprovalWorkflowOnListItem(properties.ListItem);

                                this.UpdateWorkflowStatus(properties.ListItem);
                            }
                        }
                    }
                    else if (doclibmodstatbefore == null)
                    {
                        if (levelBefore == 2 && levelAfter == 2 && doclibmodstatAfter == 3)
                        {
                            // Check to cancel workflow on cancel approvl button click.
                            // Must have levelbefore = 2, levelAfter = 2, doclibmodstatbefore = null and
                            WorkflowHelper2013.CancelApprovalWorkflowOnListItem(properties.ListItem);

                            this.UpdateWorkflowStatus(properties.ListItem);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //logging
            }
        }
 /// <summary>
 /// Asynchronous After event that occurs after an item is checked in.
 /// </summary>
 /// <param name="properties">event properties</param>
 public override void ItemCheckedIn(SPItemEventProperties properties)
 {
     try
     {
         base.ItemCheckedIn(properties);
         if (properties.ListItem.ModerationInformation.Status == SPModerationStatusType.Pending)
         {
             WorkflowHelper2013.StartApprovalWorkflowOnListItem(properties.ListItem, true);
         }
     }
     catch (Exception ex)
     {
         //Log exception
     }
 }
        /// <summary>
        /// Synchronous Before event that occurs when an existing item is changed, for example, when the user changes data in one or more fields.
        /// </summary>
        /// <param name="properties">An <see cref="T:Microsoft.SharePoint.SPItemEventProperties" /> object that represents properties of the event handler.</param>
        public override void ItemUpdating(SPItemEventProperties properties)
        {
            try
            {
                base.ItemUpdating(properties);
                object levelbefore         = properties.BeforeProperties["vti_level"];
                object levelafter          = properties.AfterProperties["vti_level"];
                object doclibmodstatbefore = properties.BeforeProperties["vti_doclibmodstat"];
                object doclibmodstatafter  = properties.AfterProperties["vti_doclibmodstat"];

                if (levelbefore != null && levelafter != null)
                {
                    int  levelBefore, levelAfter, doclibmodstatBefore = -1, doclibmodstatAfter = -1;
                    bool levelBeforeParsed, levelAfterParsed, doclibmodstatBeforeParsed = false, doclibmodstatAfterParsed = false;

                    levelBeforeParsed = int.TryParse(levelbefore.ToString(), out levelBefore);
                    levelAfterParsed  = int.TryParse(levelafter.ToString(), out levelAfter);

                    if (doclibmodstatbefore != null)
                    {
                        doclibmodstatBeforeParsed = int.TryParse(doclibmodstatbefore.ToString(), out doclibmodstatBefore);
                    }

                    if (doclibmodstatafter != null)
                    {
                        doclibmodstatAfterParsed = int.TryParse(doclibmodstatafter.ToString(), out doclibmodstatAfter);
                    }

                    if (levelBeforeParsed && levelAfterParsed && doclibmodstatAfterParsed)
                    {
                        if (doclibmodstatbefore == null)
                        {
                            // Check to Trigger workflow on Submit button click after minor check in.
                            // Must have levelbefore =2, levelAfter = 2, doclibmodstatbefore = null and doclibmodstatafter = 2
                            if (levelBefore == 2 && levelAfter == 2 && doclibmodstatAfter == 2)
                            {
                                WorkflowHelper2013.StartApprovalWorkflowOnListItem(properties.ListItem, true);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //Log exception
            }
        }