/// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            Guid?  groupGuid    = null;
            Person person       = null;
            Group  group        = null;
            string noteValue    = string.Empty;
            string captionValue = string.Empty;
            bool   isAlert      = false;

            // get the group attribute
            Guid groupAttributeGuid = GetAttributeValue(action, "Group").AsGuid();

            if (!groupAttributeGuid.IsEmpty())
            {
                groupGuid = action.GetWorklowAttributeValue(groupAttributeGuid).AsGuidOrNull();

                if (groupGuid.HasValue)
                {
                    group = new GroupService(rockContext).Get(groupGuid.Value);

                    if (group == null)
                    {
                        errorMessages.Add("The group provided does not exist.");
                    }
                }
                else
                {
                    errorMessages.Add("Invalid group provided.");
                }
            }

            // get person alias guid
            Guid   personAliasGuid = Guid.Empty;
            string personAttribute = GetAttributeValue(action, "Person");

            Guid guid = personAttribute.AsGuid();

            if (!guid.IsEmpty())
            {
                var attribute = AttributeCache.Get(guid, rockContext);
                if (attribute != null)
                {
                    string value = action.GetWorklowAttributeValue(guid);
                    personAliasGuid = value.AsGuid();
                }

                if (personAliasGuid != Guid.Empty)
                {
                    person = new PersonAliasService(rockContext).Queryable()
                             .Where(p => p.Guid.Equals(personAliasGuid))
                             .Select(p => p.Person)
                             .FirstOrDefault();
                }
                else
                {
                    errorMessages.Add("The person could not be found!");
                }
            }

            // get caption
            captionValue = GetAttributeValue(action, "Caption");
            guid         = captionValue.AsGuid();
            if (guid.IsEmpty())
            {
                captionValue = captionValue.ResolveMergeFields(GetMergeFields(action));
            }
            else
            {
                var workflowAttributeValue = action.GetWorklowAttributeValue(guid);

                if (workflowAttributeValue != null)
                {
                    captionValue = workflowAttributeValue;
                }
            }

            // get group member note
            noteValue = GetAttributeValue(action, "Note");
            guid      = noteValue.AsGuid();
            if (guid.IsEmpty())
            {
                noteValue = noteValue.ResolveMergeFields(GetMergeFields(action));
            }
            else
            {
                var workflowAttributeValue = action.GetWorklowAttributeValue(guid);

                if (workflowAttributeValue != null)
                {
                    noteValue = workflowAttributeValue;
                }
            }

            // get alert type
            string isAlertString = GetAttributeValue(action, "IsAlert");

            guid = isAlertString.AsGuid();
            if (guid.IsEmpty())
            {
                isAlert = isAlertString.AsBoolean();
            }
            else
            {
                var workflowAttributeValue = action.GetWorklowAttributeValue(guid);

                if (workflowAttributeValue != null)
                {
                    isAlert = workflowAttributeValue.AsBoolean();
                }
            }

            // get note type
            NoteTypeCache noteType     = null;
            Guid          noteTypeGuid = GetAttributeValue(action, "NoteType").AsGuid();

            if (!noteTypeGuid.IsEmpty())
            {
                noteType = NoteTypeCache.Get(noteTypeGuid, rockContext);

                if (noteType == null)
                {
                    errorMessages.Add("The note type provided does not exist.");
                }
            }
            else
            {
                errorMessages.Add("Invalid note type provided.");
            }


            // set note
            if (group != null && person != null && noteType != null)
            {
                var groupMembers = new GroupMemberService(rockContext).Queryable()
                                   .Where(m => m.Group.Guid == groupGuid && m.PersonId == person.Id).ToList();

                if (groupMembers.Count() > 0)
                {
                    foreach (var groupMember in groupMembers)
                    {
                        NoteService noteservice = new NoteService(rockContext);
                        Note        note        = new Note();
                        noteservice.Add(note);

                        note.NoteTypeId = noteType.Id;
                        note.Text       = noteValue;
                        note.IsAlert    = isAlert;
                        note.Caption    = captionValue;
                        note.EntityId   = groupMember.Id;

                        rockContext.SaveChanges();
                    }
                }
                else
                {
                    errorMessages.Add(string.Format("{0} is not a member of the group {1}.", person.FullName, group.Name));
                }
            }

            errorMessages.ForEach(m => action.AddLogEntry(m, true));

            return(true);
        }