private static RevisionAction <JiraAttachment> TransformAttachmentChange(JiraChangeItem item)
        {
            string attKey      = string.Empty;
            string attFilename = string.Empty;

            RevisionChangeType changeType;

            if (item.From == null && item.To != null)
            {
                attKey      = item.To;
                attFilename = item.ToString;
                changeType  = RevisionChangeType.Added;
            }
            else if (item.To == null && item.From != null)
            {
                attKey      = item.From;
                attFilename = item.FromString;
                changeType  = RevisionChangeType.Removed;
            }
            else
            {
                Logger.Log(LogLevel.Error, "Attachment change not handled!");
                return(null);
            }

            return(new RevisionAction <JiraAttachment>()
            {
                ChangeType = changeType,
                Value = new JiraAttachment()
                {
                    Id = attKey,
                    Filename = attFilename
                }
            });
        }
        private static RevisionAction <JiraLink> TransformLinkChange(JiraChangeItem item, string sourceItemKey, JiraProvider jira)
        {
            string             targetItemKey  = string.Empty;
            string             linkTypeString = string.Empty;
            RevisionChangeType changeType;

            if (item.From == null && item.To != null)
            {
                targetItemKey  = item.To;
                linkTypeString = item.ToString;
                changeType     = RevisionChangeType.Added;
            }
            else if (item.To == null && item.From != null)
            {
                targetItemKey  = item.From;
                linkTypeString = item.FromString;
                changeType     = RevisionChangeType.Removed;
            }
            else
            {
                Logger.Log(LogLevel.Error, $"Link change not handled!");
                return(null);
            }

            var linkType = jira.LinkTypes.FirstOrDefault(lt => linkTypeString.EndsWith(lt.Outward + " " + targetItemKey));

            if (linkType == null)
            {
                Logger.Log(LogLevel.Debug, $"Link with description \"{linkTypeString}\" is either not found or this issue ({sourceItemKey}) is not inward issue.");
                return(null);
            }
            else
            {
                if (linkType.Inward == linkType.Outward && sourceItemKey.CompareTo(targetItemKey) < 0)
                {
                    Logger.Log(LogLevel.Debug, $"Link is non-directional ({linkType.Name}) and sourceItem ({sourceItemKey}) is older then target item ({targetItemKey}). Link change will be part of target item.");
                    return(null);
                }

                return(new RevisionAction <JiraLink>()
                {
                    ChangeType = changeType,
                    Value = new JiraLink()
                    {
                        SourceItem = sourceItemKey,
                        TargetItem = targetItemKey,
                        LinkType = linkType.Name,
                    }
                });
            }
        }
        private static (string, string, string) TransformFieldChange(JiraChangeItem item, JiraProvider jira)
        {
            var objectFields = new HashSet <string>()
            {
                "assignee", "creator", "reporter"
            };
            string from, to = string.Empty;

            string fieldId = item.FieldId ?? GetCustomFieldId(item.Field, jira) ?? item.Field;

            if (objectFields.Contains(fieldId))
            {
                from = item.From;
                to   = item.To;
            }
            else
            {
                from = item.FromString;
                to   = item.ToString;
            }

            return(fieldId, from, to);
        }