public SyntaxNode RestoreTrivia(
                SyntaxNode root,
                AnnotationResolver annotationResolver = null,
                TriviaResolver triviaResolver = null)
            {
                var tokens = RecoverTokensAtEdges(root, annotationResolver);
                var map = CreateOldToNewTokensMap(tokens, triviaResolver);

                return root.ReplaceTokens(map.Keys, (o, n) => map[o]);
            }
            public SyntaxNode RestoreTrivia(
                SyntaxNode root,
                AnnotationResolver annotationResolver = null,
                TriviaResolver triviaResolver         = null
                )
            {
                var tokens = RecoverTokensAtEdges(root, annotationResolver);
                var map    = CreateOldToNewTokensMap(tokens, triviaResolver);

                return(root.ReplaceTokens(map.Keys, (o, n) => map[o]));
            }
            private Dictionary <TriviaLocation, SyntaxToken> RecoverTokensAtEdges(
                SyntaxNode root,
                AnnotationResolver annotationResolver)
            {
                var resolver = annotationResolver ?? s_defaultAnnotationResolver;

                var tokens = Enumerable.Range((int)TriviaLocation.BeforeBeginningOfSpan, TriviaLocationsCount)
                             .Cast <TriviaLocation>()
                             .ToDictionary(
                    location => location,
                    location => resolver(root, location, _annotations[location]));

                Contract.ThrowIfFalse(
                    tokens[TriviaLocation.AfterBeginningOfSpan].RawKind == 0 /* don't care */ ||
                    tokens[TriviaLocation.BeforeEndOfSpan].RawKind == 0 /* don't care */ ||
                    tokens[TriviaLocation.AfterBeginningOfSpan] == tokens[TriviaLocation.BeforeEndOfSpan] ||
                    tokens[TriviaLocation.AfterBeginningOfSpan].GetPreviousToken(includeZeroWidth: true) == tokens[TriviaLocation.BeforeEndOfSpan] ||
                    tokens[TriviaLocation.AfterBeginningOfSpan].Span.End <= tokens[TriviaLocation.BeforeEndOfSpan].SpanStart);

                return(tokens);
            }
            private Dictionary<TriviaLocation, SyntaxToken> RecoverTokensAtEdges(
                SyntaxNode root,
                AnnotationResolver annotationResolver)
            {
                var resolver = annotationResolver ?? s_defaultAnnotationResolver;

                var tokens = Enumerable.Range((int)TriviaLocation.BeforeBeginningOfSpan, TriviaLocationsCount)
                                       .Cast<TriviaLocation>()
                                       .ToDictionary(
                                            location => location,
                                            location => resolver(root, location, _annotations[location]));

                // check variable assumption. ordering of two pairs can't be changed
                Contract.ThrowIfFalse(
                    (tokens[TriviaLocation.BeforeBeginningOfSpan].RawKind == 0 && tokens[TriviaLocation.AfterEndOfSpan].RawKind == 0) ||
                    (tokens[TriviaLocation.BeforeBeginningOfSpan].RawKind == 0 /* && don't care */) ||
                    (/* don't care && */ tokens[TriviaLocation.AfterEndOfSpan].RawKind == 0) ||
                    (tokens[TriviaLocation.BeforeBeginningOfSpan].Span.End <= tokens[TriviaLocation.AfterEndOfSpan].SpanStart));

                Contract.ThrowIfFalse(
                    (tokens[TriviaLocation.AfterBeginningOfSpan].RawKind == 0 && tokens[TriviaLocation.BeforeEndOfSpan].RawKind == 0) ||
                    (tokens[TriviaLocation.AfterBeginningOfSpan].RawKind == 0 /* && don't care */) ||
                    (/* don't care && */ tokens[TriviaLocation.BeforeEndOfSpan].RawKind == 0) ||
                    (tokens[TriviaLocation.AfterBeginningOfSpan] == tokens[TriviaLocation.BeforeEndOfSpan]) ||
                    (tokens[TriviaLocation.AfterBeginningOfSpan].GetPreviousToken(includeZeroWidth: true) == tokens[TriviaLocation.BeforeEndOfSpan]) ||
                    (tokens[TriviaLocation.AfterBeginningOfSpan].Span.End <= tokens[TriviaLocation.BeforeEndOfSpan].SpanStart));

                return tokens;
            }