private void ReCalculateEditRange()
        {
            leftEditRange = new LineRange {
                start = 0, end = File.BaseLines.Length
            };
            rightEditRange = new LineRange {
                start = 0, end = File.PatchedLines.Length
            };

            int i    = File.Results.ToList().IndexOf(Result);
            var prev = File.Results.Take(i).LastOrDefault(r => r.AppliedPatch != null);

            if (prev != null)
            {
                leftEditRange.start  = prev.End1;
                rightEditRange.start = prev.End2;
            }

            var next = File.Results.Skip(i + 1).FirstOrDefault(r => r.AppliedPatch != null);

            if (next != null)
            {
                leftEditRange.end  = next.Start1;
                rightEditRange.end = next.Start2;
            }

            filePanel.SetEditableRange(rightEditRange);

            var viewPatch = Result.ViewPatch;

            if (viewPatch != null && !(leftEditRange.Contains(viewPatch.Range1) && rightEditRange.Contains(viewPatch.Range2)))
            {
                var choice = new CustomMessageBox {
                    Title   = "Patch out of order",
                    Message = "Patch does not fit between neighbours. Either patches overlap, or have different order to original file.",
                    Image   = MessageBoxImage.Error
                }.ShowDialogOk();
            }
        }
        private void RediffPatchEditor()
        {
            patchPanel.ReDiff();
            editorsInSync = false;

            var p = FormatAssistEditingPatch();

            //offset given other patches are already applied
            p.start1 += rightEditRange.start - leftEditRange.start;

            var patcher = new Patcher(new[] { p }, PatchedLinesExcludingCurrentResult);

            patcher.Patch(Patcher.Mode.FUZZY);

            var r = patcher.Results.Single();

            if (!r.success)
            {
                new CustomMessageBox {
                    Title   = "Patch Failed",
                    Message = "Patch could not be applied, please ensure that the context is correct",
                    Image   = MessageBoxImage.Error
                }.ShowDialogOk();

                return;
            }

            p = r.appliedPatch;
            var appliedRange = p.TrimmedRange1;
            // calculate Result.AppliedPatch.Range2 to match PatchedLinesExcludingCurrentResult
            var keepoutRanges = new List <LineRange>();
            int delta         = 0;

            foreach (var _result in File.Results)
            {
                if (_result == Result || !(_result.AppliedPatch is Patch applied))
                {
                    continue;
                }

                var range = new LineRange {
                    start = applied.start1 + delta, length = applied.length2
                };
                keepoutRanges.Add(range);

                delta += applied.length2 - applied.length1;

                if (range.end <= appliedRange.start)
                {
                    p.start1 -= applied.length2 - applied.length1;
                }
            }

            if (keepoutRanges.Any(range => range.Contains(appliedRange)))
            {
                new CustomMessageBox {
                    Title   = "Patch Failed",
                    Message = $"Patch applied ({r.mode}) inside another patch {appliedRange}",
                    Image   = MessageBoxImage.Error
                }.ShowDialogOk("Ignore");

                return;
            }

            CustomMessageBox msgBox = null;

            if (!new LineRange {
                start = rightEditRange.start, length = leftEditRange.length
            }.Contains(appliedRange))
            {
                msgBox = new CustomMessageBox {
                    Title   = "Moved Patch",
                    Message = "Patch has been moved.\nLoad assisted patch?",
                    Image   = MessageBoxImage.Question
                };
            }
            if (r.mode == Patcher.Mode.FUZZY)
            {
                if (msgBox == null)
                {
                    msgBox = new CustomMessageBox {
                        Title   = "Fuzzy Patch",
                        Message = "Fuzzy patch mode was required to make the patch succeed.\nLoad assisted patch?",
                        Image   = MessageBoxImage.Question
                    };
                }
                msgBox.Message += $" (Quality { (int)(r.fuzzyQuality * 100)})";
            }

            if (msgBox != null && msgBox.ShowDialogOkCancel("Load", "Undo") == MessageBoxResult.Cancel)
            {
                return;
            }

            Result.EditingPatch = p;

            filePanel.LoadDiff(File.BaseLines, patcher.ResultLines, true, false);
            ReloadEditingPatch(r.mode != Patcher.Mode.FUZZY);
            ReCalculateEditRange();
            filePanel.ScrollToMarked();
        }