text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.AsyncCompletion;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.InteractiveWindow;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data;
using Moq;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using RoslynCompletion = Microsoft.CodeAnalysis.Completion;

namespace Microsoft.CodeAnalysis.Editor.UnitTests.Completion
{
    [UseExportProvider]
    public abstract class AbstractCompletionProviderTests<TWorkspaceFixture> : TestBase
        where TWorkspaceFixture : TestWorkspaceFixture, new()
    {
        private static readonly TestComposition s_baseComposition = EditorTestCompositions.EditorFeatures.AddExcludedPartTypes(typeof(CompletionProvider));

        private readonly TestFixtureHelper<TWorkspaceFixture> _fixtureHelper = new();

        protected readonly Mock<ICompletionSession> MockCompletionSession;
        private ExportProvider _lazyExportProvider;

        protected AbstractCompletionProviderTests()
        {
            MockCompletionSession = new Mock<ICompletionSession>(MockBehavior.Strict);
        }

        protected ExportProvider ExportProvider
            => _lazyExportProvider ??= GetComposition().ExportProviderFactory.CreateExportProvider();

        protected virtual TestComposition GetComposition()
            => s_baseComposition.AddParts(GetCompletionProviderType());

        private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture()
            => _fixtureHelper.GetOrCreateFixture();

        protected static async Task<bool> CanUseSpeculativeSemanticModelAsync(Document document, int position)
        {
            var service = document.GetLanguageService<ISyntaxFactsService>();
            var node = (await document.GetSyntaxRootAsync()).FindToken(position).Parent;

            return !service.GetMemberBodySpanForSpeculativeBinding(node).IsEmpty;
        }

        internal virtual CompletionServiceWithProviders GetCompletionService(Project project)
        {
            var completionService = project.LanguageServices.GetRequiredService<CompletionService>();

            var completionServiceWithProviders = Assert.IsAssignableFrom<CompletionServiceWithProviders>(completionService);

            var completionProviders = ((IMefHostExportProvider)project.Solution.Workspace.Services.HostServices).GetExports<CompletionProvider>();
            var completionProvider = Assert.Single(completionProviders).Value;
            Assert.IsType(GetCompletionProviderType(), completionProvider);

            return completionServiceWithProviders;
        }

        internal static ImmutableHashSet<string> GetRoles(Document document)
            => document.SourceCodeKind == SourceCodeKind.Regular ? ImmutableHashSet<string>.Empty : ImmutableHashSet.Create(PredefinedInteractiveTextViewRoles.InteractiveTextViewRole);

        protected abstract string ItemPartiallyWritten(string expectedItemOrNull);

        protected abstract TestWorkspace CreateWorkspace(string fileContents);

        private protected abstract Task BaseVerifyWorkerAsync(
            string code, int position, string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
            int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription, List<CompletionFilter> matchingFilters, CompletionItemFlags? flags);

        internal static Task<RoslynCompletion.CompletionList> GetCompletionListAsync(
            CompletionService service,
            Document document,
            int position,
            RoslynCompletion.CompletionTrigger triggerInfo,
            OptionSet options = null)
        {
            return service.GetCompletionsAsync(document, position, triggerInfo, GetRoles(document), options);
        }

        private protected async Task CheckResultsAsync(
            Document document, int position, string expectedItemOrNull,
            string expectedDescriptionOrNull, bool usePreviousCharAsTrigger,
            bool checkForAbsence, int? glyph, int? matchPriority,
            bool? hasSuggestionModeItem, string displayTextSuffix, string inlineDescription,
            List<CompletionFilter> matchingFilters, CompletionItemFlags? flags)
        {
            var code = (await document.GetTextAsync()).ToString();

            var trigger = RoslynCompletion.CompletionTrigger.Invoke;

            if (usePreviousCharAsTrigger)
            {
                trigger = RoslynCompletion.CompletionTrigger.CreateInsertionTrigger(insertedCharacter: code.ElementAt(position - 1));
            }

            var completionService = GetCompletionService(document.Project);
            var completionList = await GetCompletionListAsync(completionService, document, position, trigger);
            var items = completionList == null ? ImmutableArray<RoslynCompletion.CompletionItem>.Empty : completionList.Items;

            if (hasSuggestionModeItem != null)
            {
                Assert.Equal(hasSuggestionModeItem.Value, completionList.SuggestionModeItem != null);
            }

            if (checkForAbsence)
            {
                if (items == null)
                {
                    return;
                }

                if (expectedItemOrNull == null)
                {
                    Assert.Empty(items);
                }
                else
                {
                    AssertEx.None(
                        items,
                        c => CompareItems(c.DisplayText, expectedItemOrNull)
                                && CompareItems(c.DisplayTextSuffix, displayTextSuffix ?? "")
                                && CompareItems(c.InlineDescription, inlineDescription ?? "")
                                && (expectedDescriptionOrNull != null ? completionService.GetDescriptionAsync(document, c).Result.Text == expectedDescriptionOrNull : true));
                }
            }
            else
            {
                if (expectedItemOrNull == null)
                {
                    Assert.NotEmpty(items);
                }
                else
                {
                    AssertEx.Any(items, Predicate);
                }
            }

            bool Predicate(RoslynCompletion.CompletionItem c)
            {
                if (!CompareItems(c.DisplayText, expectedItemOrNull))
                    return false;
                if (!CompareItems(c.DisplayTextSuffix, displayTextSuffix ?? ""))
                    return false;
                if (!CompareItems(c.InlineDescription, inlineDescription ?? ""))
                    return false;
                if (expectedDescriptionOrNull != null && completionService.GetDescriptionAsync(document, c).Result.Text != expectedDescriptionOrNull)
                    return false;
                if (glyph.HasValue && !c.Tags.SequenceEqual(GlyphTags.GetTags((Glyph)glyph.Value)))
                    return false;
                if (matchPriority.HasValue && c.Rules.MatchPriority != matchPriority.Value)
                    return false;
                if (matchingFilters != null && !FiltersMatch(matchingFilters, c))
                    return false;
                if (flags != null && flags.Value != c.Flags)
                    return false;

                return true;
            }
        }

        protected void SetExperimentOption(string experimentName, bool enabled)
        {
            var mockExperimentService = ExportProvider.GetExportedValue<TestExperimentationService>();
            mockExperimentService.SetExperimentOption(experimentName, enabled);
        }

        private static bool FiltersMatch(List<CompletionFilter> expectedMatchingFilters, RoslynCompletion.CompletionItem item)
        {
            var matchingFilters = FilterSet.GetFilters(item);

            // Check that the list has no duplicates.
            Assert.Equal(matchingFilters.Count, matchingFilters.Distinct().Count());
            return expectedMatchingFilters.SetEquals(matchingFilters);
        }

        private async Task VerifyAsync(
            string markup, string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
            int? glyph, int? matchPriority, bool? hasSuggestionModeItem, string displayTextSuffix,
            string inlineDescription, List<CompletionFilter> matchingFilters, CompletionItemFlags? flags)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            var workspace = workspaceFixture.Target.GetWorkspace(markup, ExportProvider);
            var code = workspaceFixture.Target.Code;
            var position = workspaceFixture.Target.Position;

            workspace.SetOptions(WithChangedOptions(workspace.Options));

            await VerifyWorkerAsync(
                code, position, expectedItemOrNull, expectedDescriptionOrNull,
                sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence, glyph,
                matchPriority, hasSuggestionModeItem, displayTextSuffix, inlineDescription,
                matchingFilters, flags).ConfigureAwait(false);
        }

        protected async Task<CompletionList> GetCompletionListAsync(string markup, string workspaceKind = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();
            var workspace = workspaceFixture.Target.GetWorkspace(markup, ExportProvider, workspaceKind: workspaceKind);
            var currentDocument = workspace.CurrentSolution.GetDocument(workspaceFixture.Target.CurrentDocument.Id);
            var position = workspaceFixture.Target.Position;
            currentDocument = WithChangedOptions(currentDocument);

            return await GetCompletionListAsync(GetCompletionService(currentDocument.Project), currentDocument, position, RoslynCompletion.CompletionTrigger.Invoke, options: workspace.Options).ConfigureAwait(false);
        }

        protected async Task VerifyCustomCommitProviderAsync(string markupBeforeCommit, string itemToCommit, string expectedCodeAfterCommit, SourceCodeKind? sourceCodeKind = null, char? commitChar = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();
            using (workspaceFixture.Target.GetWorkspace(markupBeforeCommit, ExportProvider))
            {
                var code = workspaceFixture.Target.Code;
                var position = workspaceFixture.Target.Position;

                if (sourceCodeKind.HasValue)
                {
                    await VerifyCustomCommitProviderWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, sourceCodeKind.Value, commitChar);
                }
                else
                {
                    await VerifyCustomCommitProviderWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, SourceCodeKind.Regular, commitChar);
                    await VerifyCustomCommitProviderWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, SourceCodeKind.Script, commitChar);
                }
            }
        }

        protected async Task VerifyProviderCommitAsync(
            string markupBeforeCommit,
            string itemToCommit,
            string expectedCodeAfterCommit,
            char? commitChar,
            SourceCodeKind? sourceCodeKind = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            workspaceFixture.Target.GetWorkspace(markupBeforeCommit, ExportProvider);

            var code = workspaceFixture.Target.Code;
            var position = workspaceFixture.Target.Position;

            expectedCodeAfterCommit = expectedCodeAfterCommit.NormalizeLineEndings();
            if (sourceCodeKind.HasValue)
            {
                await VerifyProviderCommitWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, commitChar, sourceCodeKind.Value);
            }
            else
            {
                await VerifyProviderCommitWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, commitChar, SourceCodeKind.Regular);
                await VerifyProviderCommitWorkerAsync(code, position, itemToCommit, expectedCodeAfterCommit, commitChar, SourceCodeKind.Script);
            }
        }

        protected bool CompareItems(string actualItem, string expectedItem)
            => GetStringComparer().Equals(actualItem, expectedItem);

        protected virtual IEqualityComparer<string> GetStringComparer()
            => StringComparer.Ordinal;

        private protected async Task VerifyItemExistsAsync(
            string markup, string expectedItem, string expectedDescriptionOrNull = null,
            SourceCodeKind? sourceCodeKind = null, bool usePreviousCharAsTrigger = false,
            int? glyph = null, int? matchPriority = null, bool? hasSuggestionModeItem = null,
            string displayTextSuffix = null, string inlineDescription = null,
            List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            if (sourceCodeKind.HasValue)
            {
                await VerifyAsync(markup, expectedItem, expectedDescriptionOrNull,
                    sourceCodeKind.Value, usePreviousCharAsTrigger, checkForAbsence: false,
                    glyph: glyph, matchPriority: matchPriority,
                    hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix,
                    inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);
            }
            else
            {
                await VerifyAsync(
                    markup, expectedItem, expectedDescriptionOrNull, SourceCodeKind.Regular, usePreviousCharAsTrigger,
                    checkForAbsence: false, glyph: glyph, matchPriority: matchPriority,
                    hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix,
                    inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);

                await VerifyAsync(
                    markup, expectedItem, expectedDescriptionOrNull, SourceCodeKind.Script, usePreviousCharAsTrigger,
                    checkForAbsence: false, glyph: glyph, matchPriority: matchPriority,
                    hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix,
                    inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);
            }
        }

        private protected async Task VerifyItemIsAbsentAsync(
            string markup, string expectedItem, string expectedDescriptionOrNull = null,
            SourceCodeKind? sourceCodeKind = null, bool usePreviousCharAsTrigger = false,
            bool? hasSuggestionModeItem = null, string displayTextSuffix = null, string inlineDescription = null,
            List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            if (sourceCodeKind.HasValue)
            {
                await VerifyAsync(markup, expectedItem, expectedDescriptionOrNull, sourceCodeKind.Value, usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);
            }
            else
            {
                await VerifyAsync(markup, expectedItem, expectedDescriptionOrNull, SourceCodeKind.Regular, usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);
                await VerifyAsync(markup, expectedItem, expectedDescriptionOrNull, SourceCodeKind.Script, usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: matchingFilters, flags: flags);
            }
        }

        protected async Task VerifyAnyItemExistsAsync(
            string markup, SourceCodeKind? sourceCodeKind = null, bool usePreviousCharAsTrigger = false,
            bool? hasSuggestionModeItem = null, string displayTextSuffix = null, string inlineDescription = null)
        {
            if (sourceCodeKind.HasValue)
            {
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: sourceCodeKind.Value, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: false, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
            }
            else
            {
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Regular, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: false, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: false, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
            }
        }

        protected async Task VerifyNoItemsExistAsync(
            string markup, SourceCodeKind? sourceCodeKind = null,
            bool usePreviousCharAsTrigger = false, bool? hasSuggestionModeItem = null,
            string displayTextSuffix = null, string inlineDescription = null)
        {
            if (sourceCodeKind.HasValue)
            {
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: sourceCodeKind.Value, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
            }
            else
            {
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Regular, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
                await VerifyAsync(markup, expectedItemOrNull: null, expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script, usePreviousCharAsTrigger: usePreviousCharAsTrigger, checkForAbsence: true, glyph: null, matchPriority: null, hasSuggestionModeItem: hasSuggestionModeItem, displayTextSuffix: displayTextSuffix, inlineDescription: inlineDescription, matchingFilters: null, flags: null);
            }
        }

        internal abstract Type GetCompletionProviderType();

        /// <summary>
        /// Override this to change parameters or return without verifying anything, e.g. for script sources. Or to test in other code contexts.
        /// </summary>
        /// <param name="code">The source code (not markup).</param>
        /// <param name="expectedItemOrNull">The expected item. If this is null, verifies that *any* item shows up for this CompletionProvider (or no items show up if checkForAbsence is true).</param>
        /// <param name="expectedDescriptionOrNull">If this is null, the Description for the item is ignored.</param>
        /// <param name="usePreviousCharAsTrigger">Whether or not the previous character in markup should be used to trigger IntelliSense for this provider. If false, invokes it through the invoke IntelliSense command.</param>
        /// <param name="checkForAbsence">If true, checks for absence of a specific item (or that no items are returned from this CompletionProvider)</param>
        private protected virtual async Task VerifyWorkerAsync(
            string code, int position,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind,
            bool usePreviousCharAsTrigger, bool checkForAbsence,
            int? glyph, int? matchPriority, bool? hasSuggestionModeItem,
            string displayTextSuffix,
            string inlineDescription,
            List<CompletionFilter> matchingFilters, CompletionItemFlags? flags)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            workspaceFixture.Target.GetWorkspace(ExportProvider);
            var document1 = workspaceFixture.Target.UpdateDocument(code, sourceCodeKind);

            await CheckResultsAsync(
                document1, position, expectedItemOrNull,
                expectedDescriptionOrNull, usePreviousCharAsTrigger,
                checkForAbsence, glyph, matchPriority,
                hasSuggestionModeItem, displayTextSuffix, inlineDescription,
                matchingFilters, flags);

            if (await CanUseSpeculativeSemanticModelAsync(document1, position))
            {
                var document2 = workspaceFixture.Target.UpdateDocument(code, sourceCodeKind, cleanBeforeUpdate: false);
                await CheckResultsAsync(
                    document2, position, expectedItemOrNull, expectedDescriptionOrNull,
                    usePreviousCharAsTrigger, checkForAbsence, glyph, matchPriority,
                    hasSuggestionModeItem, displayTextSuffix, inlineDescription,
                    matchingFilters, flags);
            }
        }

        /// <summary>
        /// Override this to change parameters or return without verifying anything, e.g. for script sources. Or to test in other code contexts.
        /// </summary>
        /// <param name="codeBeforeCommit">The source code (not markup).</param>
        /// <param name="position">Position where intellisense is invoked.</param>
        /// <param name="itemToCommit">The item to commit from the completion provider.</param>
        /// <param name="expectedCodeAfterCommit">The expected code after commit.</param>
        protected virtual async Task VerifyCustomCommitProviderWorkerAsync(string codeBeforeCommit, int position, string itemToCommit, string expectedCodeAfterCommit, SourceCodeKind sourceCodeKind, char? commitChar = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            var document1 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind);
            await VerifyCustomCommitProviderCheckResultsAsync(document1, codeBeforeCommit, position, itemToCommit, expectedCodeAfterCommit, commitChar);

            if (await CanUseSpeculativeSemanticModelAsync(document1, position))
            {
                var document2 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind, cleanBeforeUpdate: false);
                await VerifyCustomCommitProviderCheckResultsAsync(document2, codeBeforeCommit, position, itemToCommit, expectedCodeAfterCommit, commitChar);
            }
        }

        private async Task VerifyCustomCommitProviderCheckResultsAsync(Document document, string codeBeforeCommit, int position, string itemToCommit, string expectedCodeAfterCommit, char? commitChar)
        {
            document = WithChangedOptions(document);

            var service = GetCompletionService(document.Project);
            var completionLlist = await GetCompletionListAsync(service, document, position, RoslynCompletion.CompletionTrigger.Invoke);
            var items = completionLlist.Items;

            Assert.Contains(itemToCommit, items.Select(x => x.DisplayText), GetStringComparer());
            var firstItem = items.First(i => CompareItems(i.DisplayText, itemToCommit));

            if (service.GetProvider(firstItem) is ICustomCommitCompletionProvider customCommitCompletionProvider)
            {
                VerifyCustomCommitWorker(service, customCommitCompletionProvider, firstItem, codeBeforeCommit, expectedCodeAfterCommit, commitChar);
            }
            else
            {
                await VerifyCustomCommitWorkerAsync(service, document, firstItem, completionLlist.Span, codeBeforeCommit, expectedCodeAfterCommit, commitChar);
            }
        }

        protected virtual OptionSet WithChangedOptions(OptionSet options) => options;
        private Document WithChangedOptions(Document document)
        {
            var workspace = document.Project.Solution.Workspace;
            var newOptions = WithChangedOptions(workspace.Options);
            workspace.TryApplyChanges(document.Project.Solution.WithOptions(newOptions));
            return workspace.CurrentSolution.GetDocument(document.Id);
        }

        private static Document WithChangedOption(Document document, OptionKey optionKey, object value)
        {
            var workspace = document.Project.Solution.Workspace;
            var newOptions = workspace.Options.WithChangedOption(optionKey, value);
            workspace.TryApplyChanges(document.Project.Solution.WithOptions(newOptions));
            return workspace.CurrentSolution.GetDocument(document.Id);
        }

        private async Task VerifyCustomCommitWorkerAsync(
            CompletionServiceWithProviders service,
            Document document,
            RoslynCompletion.CompletionItem completionItem,
            TextSpan completionListSpan,
            string codeBeforeCommit,
            string expectedCodeAfterCommit,
            char? commitChar = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            MarkupTestFile.GetPosition(expectedCodeAfterCommit, out var actualExpectedCode, out int expectedCaretPosition);

            if (commitChar.HasValue &&
                !CommitManager.IsCommitCharacter(service.GetRules(), completionItem, commitChar.Value))
            {
                Assert.Equal(codeBeforeCommit, actualExpectedCode);
                return;
            }

            // textview is created lazily, so need to access it before making
            // changes to document, so the cursor position is tracked correctly.
            var textView = workspaceFixture.Target.CurrentDocument.GetTextView();

            var options = await document.GetOptionsAsync().ConfigureAwait(false);
            var disallowAddingImports = options.GetOption(CompletionServiceOptions.DisallowAddingImports);

            var commit = await service.GetChangeAsync(document, completionItem, completionListSpan, commitChar, disallowAddingImports, CancellationToken.None);

            var text = await document.GetTextAsync();
            var newText = text.WithChanges(commit.TextChange);
            var newDoc = document.WithText(newText);
            document.Project.Solution.Workspace.TryApplyChanges(newDoc.Project.Solution);

            var textBuffer = workspaceFixture.Target.CurrentDocument.GetTextBuffer();

            var actualCodeAfterCommit = textBuffer.CurrentSnapshot.AsText().ToString();
            var caretPosition = commit.NewPosition ?? textView.Caret.Position.BufferPosition.Position;

            AssertEx.EqualOrDiff(actualExpectedCode, actualCodeAfterCommit);
            Assert.Equal(expectedCaretPosition, caretPosition);
        }

        private void VerifyCustomCommitWorker(
            CompletionService service,
            ICustomCommitCompletionProvider customCommitCompletionProvider,
            RoslynCompletion.CompletionItem completionItem,
            string codeBeforeCommit,
            string expectedCodeAfterCommit,
            char? commitChar = null)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            MarkupTestFile.GetPosition(expectedCodeAfterCommit, out var actualExpectedCode, out int expectedCaretPosition);

            if (commitChar.HasValue &&
                !CommitManager.IsCommitCharacter(service.GetRules(), completionItem, commitChar.Value))
            {
                Assert.Equal(codeBeforeCommit, actualExpectedCode);
                return;
            }

            // textview is created lazily, so need to access it before making
            // changes to document, so the cursor position is tracked correctly.
            var textView = workspaceFixture.Target.CurrentDocument.GetTextView();
            var textBuffer = workspaceFixture.Target.CurrentDocument.GetTextBuffer();

            customCommitCompletionProvider.Commit(completionItem, textView, textBuffer, textView.TextSnapshot, commitChar);

            var actualCodeAfterCommit = textBuffer.CurrentSnapshot.AsText().ToString();
            var caretPosition = textView.Caret.Position.BufferPosition.Position;

            Assert.Equal(actualExpectedCode, actualCodeAfterCommit);
            Assert.Equal(expectedCaretPosition, caretPosition);
        }

        /// <summary>
        /// Override this to change parameters or return without verifying anything, e.g. for script sources. Or to test in other code contexts.
        /// </summary>
        /// <param name="codeBeforeCommit">The source code (not markup).</param>
        /// <param name="position">Position where intellisense is invoked.</param>
        /// <param name="itemToCommit">The item to commit from the completion provider.</param>
        /// <param name="expectedCodeAfterCommit">The expected code after commit.</param>
        private async Task VerifyProviderCommitWorkerAsync(string codeBeforeCommit, int position, string itemToCommit, string expectedCodeAfterCommit,
            char? commitChar, SourceCodeKind sourceCodeKind)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            var document1 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind);
            await VerifyProviderCommitCheckResultsAsync(document1, position, itemToCommit, expectedCodeAfterCommit, commitChar);

            if (await CanUseSpeculativeSemanticModelAsync(document1, position))
            {
                var document2 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind, cleanBeforeUpdate: false);
                await VerifyProviderCommitCheckResultsAsync(document2, position, itemToCommit, expectedCodeAfterCommit, commitChar);
            }
        }

        private async Task VerifyProviderCommitCheckResultsAsync(
            Document document, int position, string itemToCommit, string expectedCodeAfterCommit, char? commitCharOpt)
        {
            document = WithChangedOptions(document);
            var service = GetCompletionService(document.Project);
            var completionList = await GetCompletionListAsync(service, document, position, RoslynCompletion.CompletionTrigger.Invoke);
            var items = completionList.Items;
            var firstItem = items.First(i => CompareItems(i.DisplayText + i.DisplayTextSuffix, itemToCommit));

            var commitChar = commitCharOpt ?? '\t';

            var text = await document.GetTextAsync();

            if (commitChar == '\t' ||
                CommitManager.IsCommitCharacter(service.GetRules(), firstItem, commitChar))
            {
                var textChange = (await service.GetChangeAsync(document, firstItem, completionList.Span, commitChar, disallowAddingImports: false, CancellationToken.None)).TextChange;

                // Adjust TextChange to include commit character, so long as it isn't TAB.
                if (commitChar != '\t')
                {
                    textChange = new TextChange(textChange.Span, textChange.NewText.TrimEnd(commitChar) + commitChar);
                }

                text = text.WithChanges(textChange);
            }
            else
            {
                // nothing was committed, but we should insert the commit character.
                var textChange = new TextChange(new TextSpan(firstItem.Span.End, 0), commitChar.ToString());
                text = text.WithChanges(textChange);
            }

            Assert.Equal(expectedCodeAfterCommit, text.ToString());
        }

        protected async Task VerifyItemInEditorBrowsableContextsAsync(
            string markup, string referencedCode, string item, int expectedSymbolsSameSolution, int expectedSymbolsMetadataReference,
            string sourceLanguage, string referencedLanguage, bool hideAdvancedMembers = false)
        {
            await VerifyItemWithMetadataReferenceAsync(markup, referencedCode, item, expectedSymbolsMetadataReference, sourceLanguage, referencedLanguage, hideAdvancedMembers);
            await VerifyItemWithProjectReferenceAsync(markup, referencedCode, item, expectedSymbolsSameSolution, sourceLanguage, referencedLanguage, hideAdvancedMembers);

            // If the source and referenced languages are different, then they cannot be in the same project
            if (sourceLanguage == referencedLanguage)
            {
                await VerifyItemInSameProjectAsync(markup, referencedCode, item, expectedSymbolsSameSolution, sourceLanguage, hideAdvancedMembers);
            }
        }

        protected Task VerifyItemWithMetadataReferenceAsync(string markup, string metadataReferenceCode, string expectedItem, int expectedSymbols,
                                                           string sourceLanguage, string referencedLanguage, bool hideAdvancedMembers)
        {
            var xmlString = CreateMarkupForProjectWithMetadataReference(markup, metadataReferenceCode, sourceLanguage, referencedLanguage);

            return VerifyItemWithReferenceWorkerAsync(xmlString, expectedItem, expectedSymbols, hideAdvancedMembers);
        }

        protected static string GetMarkupWithReference(string currentFile, string referencedFile, string sourceLanguage, string referenceLanguage, bool isProjectReference)
        {
            return isProjectReference
                ? CreateMarkupForProjectWithProjectReference(currentFile, referencedFile, sourceLanguage, referenceLanguage)
                : CreateMarkupForProjectWithMetadataReference(currentFile, referencedFile, sourceLanguage, referenceLanguage);
        }

        protected static string CreateMarkupForProjectWithMetadataReference(string markup, string metadataReferenceCode, string sourceLanguage, string referencedLanguage)
        {
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"" AssemblyName=""Project1"">
        <Document FilePath=""SourceDocument"">{1}</Document>
        <MetadataReferenceFromSource Language=""{2}"" CommonReferences=""true"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
            <Document FilePath=""ReferencedDocument"">{3}</Document>
        </MetadataReferenceFromSource>
    </Project>
</Workspace>", sourceLanguage, SecurityElement.Escape(markup), referencedLanguage, SecurityElement.Escape(metadataReferenceCode));
        }

        protected Task VerifyItemWithAliasedMetadataReferencesAsync(string markup, string metadataAlias, string expectedItem, int expectedSymbols,
            string sourceLanguage, string referencedLanguage, bool hideAdvancedMembers)
        {
            var xmlString = CreateMarkupForProjectWithAliasedMetadataReference(markup, metadataAlias, "", sourceLanguage, referencedLanguage);

            return VerifyItemWithReferenceWorkerAsync(xmlString, expectedItem, expectedSymbols, hideAdvancedMembers);
        }

        protected static string CreateMarkupForProjectWithAliasedMetadataReference(string markup, string metadataAlias, string referencedCode, string sourceLanguage, string referencedLanguage, bool hasGlobalAlias = true)
        {
            var aliases = hasGlobalAlias ? $"{metadataAlias},{MetadataReferenceProperties.GlobalAlias}" : $"{metadataAlias}";
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"" AssemblyName=""Project1"">
        <Document FilePath=""SourceDocument"">{1}</Document>
        <MetadataReferenceFromSource Language=""{2}"" CommonReferences=""true"" Aliases=""{3}"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
            <Document FilePath=""ReferencedDocument"">{4}</Document>
        </MetadataReferenceFromSource>
    </Project>
</Workspace>", sourceLanguage, SecurityElement.Escape(markup), referencedLanguage, SecurityElement.Escape(aliases), SecurityElement.Escape(referencedCode));
        }

        protected Task VerifyItemWithProjectReferenceAsync(string markup, string referencedCode, string expectedItem, int expectedSymbols, string sourceLanguage, string referencedLanguage, bool hideAdvancedMembers)
        {
            var xmlString = CreateMarkupForProjectWithProjectReference(markup, referencedCode, sourceLanguage, referencedLanguage);

            return VerifyItemWithReferenceWorkerAsync(xmlString, expectedItem, expectedSymbols, hideAdvancedMembers);
        }

        protected static string CreateMarkupForProjectWithAliasedProjectReference(string markup, string projectAlias, string referencedCode, string sourceLanguage, string referencedLanguage)
        {
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"" AssemblyName=""Project1"">
        <ProjectReference Alias=""{4}"">ReferencedProject</ProjectReference>
        <Document FilePath=""SourceDocument"">{1}</Document>
    </Project>
    <Project Language=""{2}"" CommonReferences=""true"" AssemblyName=""ReferencedProject"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
        <Document FilePath=""ReferencedDocument"">{3}</Document>
    </Project>

</Workspace>", sourceLanguage, SecurityElement.Escape(markup), referencedLanguage, SecurityElement.Escape(referencedCode), SecurityElement.Escape(projectAlias));
        }

        protected static string CreateMarkupForProjectWithProjectReference(string markup, string referencedCode, string sourceLanguage, string referencedLanguage)
        {
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"" AssemblyName=""Project1"">
        <ProjectReference>ReferencedProject</ProjectReference>
        <Document FilePath=""SourceDocument"">{1}</Document>
    </Project>
    <Project Language=""{2}"" CommonReferences=""true"" AssemblyName=""ReferencedProject"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
        <Document FilePath=""ReferencedDocument"">{3}</Document>
    </Project>

</Workspace>", sourceLanguage, SecurityElement.Escape(markup), referencedLanguage, SecurityElement.Escape(referencedCode));
        }

        protected static string CreateMarkupForProjectWithMultupleProjectReferences(string sourceText, string sourceLanguage, string referencedLanguage, string[] referencedTexts)
        {
            return $@"
<Workspace>
    <Project Language=""{sourceLanguage}"" CommonReferences=""true"" AssemblyName=""Project1"">
{GetProjectReferenceElements(referencedTexts)}
        <Document FilePath=""SourceDocument"">{SecurityElement.Escape(sourceText)}</Document>
    </Project>
{GetReferencedProjectElements(referencedLanguage, referencedTexts)}
</Workspace>";

            static string GetProjectReferenceElements(string[] referencedTexts)
            {
                var builder = new StringBuilder();
                for (var i = 0; i < referencedTexts.Length; ++i)
                {
                    builder.AppendLine($"<ProjectReference>ReferencedProject{i}</ProjectReference>");
                }

                return builder.ToString();
            }

            static string GetReferencedProjectElements(string language, string[] referencedTexts)
            {
                var builder = new StringBuilder();
                for (var i = 0; i < referencedTexts.Length; ++i)
                {
                    builder.Append($@"
<Project Language=""{language}"" CommonReferences=""true"" AssemblyName=""ReferencedProject{i}"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
  <Document FilePath=""ReferencedDocument{i}"">{SecurityElement.Escape(referencedTexts[i])}</Document>
</Project>");
                }

                return builder.ToString();
            }
        }

        protected static string CreateMarkupForProjecWithVBProjectReference(string markup, string referencedCode, string sourceLanguage, string rootNamespace = "")
        {
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"" AssemblyName=""Project1"">
        <ProjectReference>ReferencedProject</ProjectReference>
        <Document FilePath=""SourceDocument"">{1}</Document>
    </Project>
    <Project Language=""{2}"" CommonReferences=""true"" AssemblyName=""ReferencedProject"" IncludeXmlDocComments=""true"" DocumentationMode=""Diagnose"">
        <Document FilePath=""ReferencedDocument"">{3}</Document>
        <CompilationOptions RootNamespace=""{4}""/>
    </Project>

</Workspace>", sourceLanguage, SecurityElement.Escape(markup), LanguageNames.VisualBasic, SecurityElement.Escape(referencedCode), rootNamespace);
        }

        private Task VerifyItemInSameProjectAsync(string markup, string referencedCode, string expectedItem, int expectedSymbols, string sourceLanguage, bool hideAdvancedMembers)
        {
            var xmlString = CreateMarkupForSingleProject(markup, referencedCode, sourceLanguage);

            return VerifyItemWithReferenceWorkerAsync(xmlString, expectedItem, expectedSymbols, hideAdvancedMembers);
        }

        protected static string CreateMarkupForSingleProject(string markup, string referencedCode, string sourceLanguage)
        {
            return string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferences=""true"">
        <Document FilePath=""SourceDocument"">{1}</Document>
        <Document FilePath=""ReferencedDocument"">{2}</Document>
    </Project>
</Workspace>", sourceLanguage, SecurityElement.Escape(markup), SecurityElement.Escape(referencedCode));
        }

        private async Task VerifyItemWithReferenceWorkerAsync(
            string xmlString, string expectedItem, int expectedSymbols, bool hideAdvancedMembers)
        {
            using (var testWorkspace = TestWorkspace.Create(xmlString, exportProvider: ExportProvider))
            {
                var position = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").CursorPosition.Value;
                var solution = testWorkspace.CurrentSolution;
                var documentId = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").Id;
                var document = solution.GetDocument(documentId);

                var optionKey = new OptionKey(CompletionOptions.HideAdvancedMembers, document.Project.Language);
                document = WithChangedOption(document, optionKey, hideAdvancedMembers);

                var triggerInfo = RoslynCompletion.CompletionTrigger.Invoke;

                var completionService = GetCompletionService(document.Project);
                var completionList = await GetCompletionListAsync(completionService, document, position, triggerInfo);

                if (expectedSymbols >= 1)
                {
                    Assert.NotNull(completionList);
                    AssertEx.Any(completionList.Items, c => CompareItems(c.DisplayText, expectedItem));

                    var item = completionList.Items.First(c => CompareItems(c.DisplayText, expectedItem));
                    var description = await completionService.GetDescriptionAsync(document, item);

                    if (expectedSymbols == 1)
                    {
                        Assert.DoesNotContain("+", description.Text, StringComparison.Ordinal);
                    }
                    else
                    {
                        Assert.Contains(GetExpectedOverloadSubstring(expectedSymbols), description.Text, StringComparison.Ordinal);
                    }
                }
                else
                {
                    if (completionList != null)
                    {
                        AssertEx.None(completionList.Items, c => CompareItems(c.DisplayText, expectedItem));
                    }
                }
            }
        }

        protected Task VerifyItemWithMscorlib45Async(string markup, string expectedItem, string expectedDescription, string sourceLanguage)
        {
            var xmlString = string.Format(@"
<Workspace>
    <Project Language=""{0}"" CommonReferencesNet45=""true"">
        <Document FilePath=""SourceDocument"">
{1}
        </Document>
    </Project>
</Workspace>", sourceLanguage, SecurityElement.Escape(markup));

            return VerifyItemWithMscorlib45WorkerAsync(xmlString, expectedItem, expectedDescription);
        }

        private async Task VerifyItemWithMscorlib45WorkerAsync(
            string xmlString, string expectedItem, string expectedDescription)
        {
            using (var testWorkspace = TestWorkspace.Create(xmlString, exportProvider: ExportProvider))
            {
                var position = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").CursorPosition.Value;
                var solution = testWorkspace.CurrentSolution;
                var documentId = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").Id;
                var document = solution.GetDocument(documentId);

                var triggerInfo = RoslynCompletion.CompletionTrigger.Invoke;
                var completionService = GetCompletionService(document.Project);
                var completionList = await GetCompletionListAsync(completionService, document, position, triggerInfo);

                var item = completionList.Items.FirstOrDefault(i => i.DisplayText == expectedItem);
                Assert.Equal(expectedDescription, (await completionService.GetDescriptionAsync(document, item)).Text);
            }
        }

        private const char NonBreakingSpace = (char)0x00A0;

        private static string GetExpectedOverloadSubstring(int expectedSymbols)
        {
            if (expectedSymbols <= 1)
            {
                throw new ArgumentOutOfRangeException(nameof(expectedSymbols));
            }

            return "+" + NonBreakingSpace + (expectedSymbols - 1) + NonBreakingSpace + FeaturesResources.overload;
        }

        protected async Task VerifyItemInLinkedFilesAsync(string xmlString, string expectedItem, string expectedDescription)
        {
            using (var testWorkspace = TestWorkspace.Create(xmlString, exportProvider: ExportProvider))
            {
                var position = testWorkspace.Documents.First().CursorPosition.Value;
                var solution = testWorkspace.CurrentSolution;
                var textContainer = testWorkspace.Documents.First().GetTextBuffer().AsTextContainer();
                var currentContextDocumentId = testWorkspace.GetDocumentIdInCurrentContext(textContainer);
                var document = solution.GetDocument(currentContextDocumentId);

                var triggerInfo = RoslynCompletion.CompletionTrigger.Invoke;
                var completionService = GetCompletionService(document.Project);
                var completionList = await GetCompletionListAsync(completionService, document, position, triggerInfo);

                var item = completionList.Items.Single(c => c.DisplayText == expectedItem);
                Assert.NotNull(item);
                if (expectedDescription != null)
                {
                    var actualDescription = (await completionService.GetDescriptionAsync(document, item)).Text;
                    Assert.Equal(expectedDescription, actualDescription);
                }
            }
        }

        private protected Task VerifyAtPositionAsync(
            string code, int position, string insertText, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence,
            int? glyph, int? matchPriority, bool? hasSuggestionItem,
            string displayTextSuffix, string inlineDescription = null,
            List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            code = code.Substring(0, position) + insertText + code.Substring(position);
            position += insertText.Length;

            return BaseVerifyWorkerAsync(code, position,
                expectedItemOrNull, expectedDescriptionOrNull,
                sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence,
                glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
                inlineDescription, matchingFilters, flags);
        }

        private protected Task VerifyAtPositionAsync(
            string code, int position, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
            int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            return VerifyAtPositionAsync(
                code, position, string.Empty, usePreviousCharAsTrigger,
                expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind, checkForAbsence,
                glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
                inlineDescription, matchingFilters, flags);
        }

        private protected async Task VerifyAtEndOfFileAsync(
            string code, int position, string insertText, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
            int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            // only do this if the placeholder was at the end of the text.
            if (code.Length != position)
            {
                return;
            }

            code = code.Substring(startIndex: 0, length: position) + insertText;
            position += insertText.Length;

            await BaseVerifyWorkerAsync(
                code, position, expectedItemOrNull, expectedDescriptionOrNull,
                sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence, glyph,
                matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
                matchingFilters, flags);
        }

        private protected Task VerifyAtPosition_ItemPartiallyWrittenAsync(
            string code, int position, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
            int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            return VerifyAtPositionAsync(
                code, position, ItemPartiallyWritten(expectedItemOrNull), usePreviousCharAsTrigger,
                expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind,
                checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
                matchingFilters, flags);
        }

        private protected Task VerifyAtEndOfFileAsync(
            string code, int position, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
            int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            return VerifyAtEndOfFileAsync(code, position, string.Empty, usePreviousCharAsTrigger,
                expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind,
                checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
                inlineDescription, matchingFilters, flags);
        }

        private protected Task VerifyAtEndOfFile_ItemPartiallyWrittenAsync(
            string code, int position, bool usePreviousCharAsTrigger,
            string expectedItemOrNull, string expectedDescriptionOrNull,
            SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
            int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
            string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
        {
            return VerifyAtEndOfFileAsync(
                code, position, ItemPartiallyWritten(expectedItemOrNull), usePreviousCharAsTrigger,
                expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind, checkForAbsence,
                glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
                matchingFilters, flags);
        }

        protected void VerifyTextualTriggerCharacter(
            string markup,
            bool shouldTriggerWithTriggerOnLettersEnabled,
            bool shouldTriggerWithTriggerOnLettersDisabled,
            SourceCodeKind sourceCodeKind = SourceCodeKind.Regular,
            bool showCompletionInArgumentLists = true)
        {
            VerifyTextualTriggerCharacterWorker(markup, expectedTriggerCharacter: shouldTriggerWithTriggerOnLettersEnabled, triggerOnLetter: true, sourceCodeKind, showCompletionInArgumentLists);
            VerifyTextualTriggerCharacterWorker(markup, expectedTriggerCharacter: shouldTriggerWithTriggerOnLettersDisabled, triggerOnLetter: false, sourceCodeKind, showCompletionInArgumentLists: false);
        }

        private void VerifyTextualTriggerCharacterWorker(
            string markup,
            bool expectedTriggerCharacter,
            bool triggerOnLetter,
            SourceCodeKind sourceCodeKind,
            bool showCompletionInArgumentLists)
        {
            using (var workspace = CreateWorkspace(markup))
            {
                var hostDocument = workspace.DocumentWithCursor;
                workspace.OnDocumentSourceCodeKindChanged(hostDocument.Id, sourceCodeKind);

                Assert.Same(hostDocument, workspace.Documents.Single());
                var position = hostDocument.CursorPosition.Value;
                var text = hostDocument.GetTextBuffer().CurrentSnapshot.AsText();
                var options = workspace.Options
                    .WithChangedOption(CompletionOptions.TriggerOnTypingLetters2, hostDocument.Project.Language, triggerOnLetter)
                    .WithChangedOption(CompletionOptions.TriggerInArgumentLists, hostDocument.Project.Language, showCompletionInArgumentLists);
                var trigger = RoslynCompletion.CompletionTrigger.CreateInsertionTrigger(text[position]);

                var document = workspace.CurrentSolution.GetDocument(hostDocument.Id);
                var service = GetCompletionService(document.Project);
                var isTextualTriggerCharacterResult = service.ShouldTriggerCompletion(text, position + 1, trigger, GetRoles(document), options);

                if (expectedTriggerCharacter)
                {
                    var assertText = "'" + text.ToString(new TextSpan(position, 1)) + "' expected to be textual trigger character";
                    Assert.True(isTextualTriggerCharacterResult, assertText);
                }
                else
                {
                    var assertText = "'" + text.ToString(new TextSpan(position, 1)) + "' expected to NOT be textual trigger character";
                    Assert.False(isTextualTriggerCharacterResult, assertText);
                }
            }
        }

        protected async Task VerifyCommonCommitCharactersAsync(string initialMarkup, string textTypedSoFar)
        {
            var commitCharacters = new[]
            {
                ' ', '{', '}', '[', ']', '(', ')', '.', ',', ':',
                ';', '+', '-', '*', '/', '%', '&', '|', '^', '!',
                '~', '=', '<', '>', '?', '@', '#', '\'', '\"', '\\'
            };

            await VerifyCommitCharactersAsync(initialMarkup, textTypedSoFar, commitCharacters);
        }

        protected async Task VerifyCommitCharactersAsync(string initialMarkup, string textTypedSoFar, char[] validChars, char[] invalidChars = null, SourceCodeKind sourceCodeKind = SourceCodeKind.Regular)
        {
            Assert.NotNull(validChars);
            invalidChars = invalidChars ?? new[] { 'x' };

            using (var workspace = CreateWorkspace(initialMarkup))
            {
                var hostDocument = workspace.DocumentWithCursor;
                workspace.OnDocumentSourceCodeKindChanged(hostDocument.Id, sourceCodeKind);

                var documentId = workspace.GetDocumentId(hostDocument);
                var document = workspace.CurrentSolution.GetDocument(documentId);
                var position = hostDocument.CursorPosition.Value;

                var service = GetCompletionService(document.Project);
                var completionList = await GetCompletionListAsync(service, document, position, RoslynCompletion.CompletionTrigger.Invoke);
                var item = completionList.Items.First(i => i.DisplayText.StartsWith(textTypedSoFar));

                foreach (var ch in validChars)
                {
                    Assert.True(CommitManager.IsCommitCharacter(
                        service.GetRules(), item, ch), $"Expected '{ch}' to be a commit character");
                }

                foreach (var ch in invalidChars)
                {
                    Assert.False(CommitManager.IsCommitCharacter(
                        service.GetRules(), item, ch), $"Expected '{ch}' NOT to be a commit character");
                }
            }
        }

        protected async Task<ImmutableArray<RoslynCompletion.CompletionItem>> GetCompletionItemsAsync(
            string markup, SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger = false)
        {
            using var workspaceFixture = GetOrCreateWorkspaceFixture();

            workspaceFixture.Target.GetWorkspace(markup, ExportProvider);
            var code = workspaceFixture.Target.Code;
            var position = workspaceFixture.Target.Position;
            var document = workspaceFixture.Target.UpdateDocument(code, sourceCodeKind);

            var trigger = usePreviousCharAsTrigger
                ? RoslynCompletion.CompletionTrigger.CreateInsertionTrigger(insertedCharacter: code.ElementAt(position - 1))
                : RoslynCompletion.CompletionTrigger.Invoke;

            var completionService = GetCompletionService(document.Project);
            var completionList = await GetCompletionListAsync(completionService, document, position, trigger);

            return completionList == null ? ImmutableArray<RoslynCompletion.CompletionItem>.Empty : completionList.Items;
        }
    }
}


text: A small clone of [2048](https://github.com/gabrielecirulli/2048)

redpajama_set_name: RedPajamaGithub


text:
using Serenity.CodeGenerator;
using System.Xml.Linq;

namespace Serenity.Tests
{
    public class MockBuildProject : IBuildProject
    {
        private readonly XElement project;

        public MockBuildProject(IFileSystem fileSystem, string path)
        {
            if (fileSystem == null)
                throw new ArgumentNullException(nameof(fileSystem));

            if (path == null)
                throw new ArgumentNullException(nameof(path));

            project = XElement.Load(fileSystem.File.ReadAllText(path));
        }

        public IEnumerable<IBuildProjectItem> AllEvaluatedItems =>
            project.Elements("ItemGroup").SelectMany(x => x.Elements())
                .Select(x => new MockBuildProjectItem(x));
    }
}


text:
<?php

/*
* CLADE
* Data Collections
*/

function clade_data_download_button() {
  $files = array();
  $pdf = get_field('pdf');
  if($pdf) $files[] = $pdf;
  $csv = get_field('csv');
  if($csv) $files[] = $csv;

  $other = get_field('data_other_files');
  if($other) {
    foreach($other as $other_file) {
      $files[] = $other_file['file'];
    }
  }

  $tag = 'a';
  $href = $files[0]['url'];

  if(count($files) > 1) :
    $tag = 'span';
    $href = '';
  endif;
  ?>
  <<?php echo $tag; ?> class="button button-small file-download" href="<?php echo $href; ?>">

    <?php _e('Download', 'clade'); ?>
    <?php if(count($files) > 1) : ?>
      <?php
        foreach($files as $file) :
          $ext = wp_check_filetype($file['filename'])['ext'];
          ?><a href="<?php echo $file['url']; ?>"><?php echo $ext; ?><?php
        endforeach;
      ?>
    <?php endif; ?>
  </<?php echo $tag; ?>>
  <?php
}

class Clade_Data_Collections {

  function __construct() {
    add_action('init', array($this, 'register_post_type'));
    add_action('init', array($this, 'register_taxonomy'));

    add_filter('manage_posts_columns', array($this, 'admin_columns'));
    add_action('manage_posts_custom_column', array($this, 'admin_columns_content'), 10, 2);

    add_shortcode('data-collection', array($this, 'data_collection_shortcode'));
  }

  function admin_columns($defaults) {
    global $wp_query;
    if($wp_query->get('post_type') == 'data-collection') {
      $columns = array();
      foreach($defaults as $key => $title) {
        // Replace title for theme
        if($key !== 'title') {
          $columns[$key] = $title;
        } else {
          $columns['theme'] = __('Theme', 'clade');
          $columns['id'] = __('ID', 'clade');
        }
        // Files after date
        if($key == 'date')
          $columns['files'] = __('Files', 'clade');
      }
      $defaults = $columns;
    }
    return $defaults;
  }

  function admin_columns_content($column_name, $post_id) {
    if($column_name == 'id') {
      echo '' . $post_id . '';
    }
    if($column_name == 'theme') {
      $theme = get_field('theme', $post_id);
      echo get_the_title($theme->ID);
    }
    if($column_name == 'files') {
      $files = array(
        'pdf' => get_field('pdf', $post_id),
        'csv' => get_field('csv', $post_id)
      );
      foreach($files as $format => $file) {
        if($file) {
          echo '' . $format . ' ';
        }
      }
    }
  }

  function get_data_categories_ids($post_id = false) {
    global $post;
    $post_id = $post_id ? $post_id : $post->ID;

    $terms = get_the_terms($post_id, 'data-category');
    $ids = array();
    foreach($terms as $term) {
      $ids[] = $term->term_id;
    }
    return $ids;
  }

  function register_post_type() {
    $labels = array(
      'name'               => _x( 'Data collections', 'post type general name', 'clade' ),
      'singular_name'      => _x( 'Data collection', 'post type singular name', 'clade' ),
      'menu_name'          => _x( 'Data collections', 'admin menu', 'clade' ),
      'name_admin_bar'     => _x( 'Data collection', 'add new on admin bar', 'clade' ),
      'add_new'            => _x( 'Add new', 'data collection', 'clade' ),
      'add_new_item'       => __( 'Add new data collection', 'clade' ),
      'new_item'           => __( 'New data collection', 'clade' ),
      'edit_item'          => __( 'Edit data collection item', 'clade' ),
      'view_item'          => __( 'View data collection', 'clade' ),
      'all_items'          => __( 'All data collections', 'clade' ),
      'search_items'       => __( 'Search data collections', 'clade' ),
      'parent_item_colon'  => __( 'Parent data collections:', 'clade' ),
      'not_found'          => __( 'No data collections found.', 'clade' ),
      'not_found_in_trash' => __( 'No data collections found in trash.', 'clade' )
    );
    $args = array(
      'labels'             => $labels,
      'description'        => __( 'CLADE Data Collections', 'clade' ),
      'public'             => true,
      'publicly_queryable' => true,
      'show_ui'            => true,
      'show_in_menu'       => true,
      'query_var'          => true,
      'rewrite'            => array( 'slug' => 'data-collections' ),
      'capability_type'    => 'post',
      'has_archive'        => true,
      'hierarchical'       => false,
      'menu_position'      => 5,
      'supports'           => array('excerpt')
    );
    register_post_type( 'data-collection', $args );
  }

  function register_taxonomy() {

    // Add new taxonomy, NOT hierarchical (like tags)
    $labels = array(
      'name'                       => _x( 'Data categories', 'taxonomy general name', 'clade' ),
      'singular_name'              => _x( 'Data category', 'taxonomy singular name', 'clade' ),
      'search_items'               => __( 'Search data categories', 'clade' ),
      'popular_items'              => __( 'Popular data categories', 'clade' ),
      'all_items'                  => __( 'All data categories', 'clade' ),
      'parent_item'                => null,
      'parent_item_colon'          => null,
      'edit_item'                  => __( 'Edit data category', 'clade' ),
      'update_item'                => __( 'Update data category', 'clade' ),
      'add_new_item'               => __( 'Add New data category', 'clade' ),
      'new_item_name'              => __( 'New data category Name', 'clade' ),
      'separate_items_with_commas' => __( 'Separate writers with commas', 'clade' ),
      'add_or_remove_items'        => __( 'Add or remove writers', 'clade' ),
      'choose_from_most_used'      => __( 'Choose from the most used writers', 'clade' ),
      'not_found'                  => __( 'No writers found.', 'clade' ),
      'menu_name'                  => __( 'Data categories', 'clade' ),
    );

    $args = array(
      'hierarchical'          => true,
      'labels'                => $labels,
      'show_ui'               => true,
      'show_admin_column'     => true,
      'update_count_callback' => '_update_post_term_count',
      'query_var'             => true,
      'rewrite'               => array( 'slug' => 'data-category' ),
    );

    register_taxonomy( 'data-category', 'data-collection', $args );

  }

  function get_data_collection($post_id = false) {
    global $post;
    $post_id = $post_id ? $post_id : $post->ID;

    global $data_query;
    $data_query = new WP_Query(array(
      'p' => $post_id,
      'post_type' => 'data-collection'
    ));
    ob_start();
    get_template_part('parts/chart');
    return ob_get_clean();
  }

  function data_collection_shortcode($atts) {
    $atts = shortcode_atts(array(
      'id' => false
    ), $atts, 'data-collection');

    return $this->get_data_collection($atts['id']);
  }

}

$clade_data_collections = new Clade_Data_Collections();

function clade_get_data_categories_ids($post_id = false) {
  global $clade_data_collections;
  return $clade_data_collections->get_data_categories_ids($post_id);
}


text:
package de.mineformers.investiture.allomancy.impl;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import de.mineformers.investiture.allomancy.api.Allomancer;
import de.mineformers.investiture.allomancy.api.AllomancyAPI;
import de.mineformers.investiture.allomancy.api.Capabilities;
import de.mineformers.investiture.allomancy.api.MistingFactory;
import de.mineformers.investiture.allomancy.api.metal.Metal;
import de.mineformers.investiture.allomancy.api.metal.MetalMapping;
import de.mineformers.investiture.allomancy.api.metal.Metals;
import de.mineformers.investiture.allomancy.api.metal.stack.MetalStack;
import de.mineformers.investiture.allomancy.api.misting.Inject;
import de.mineformers.investiture.allomancy.api.misting.Misting;
import de.mineformers.investiture.allomancy.api.misting.mental.Rioter;
import de.mineformers.investiture.allomancy.api.misting.mental.Soother;
import de.mineformers.investiture.allomancy.api.misting.physical.Coinshot;
import de.mineformers.investiture.allomancy.api.misting.physical.Lurcher;
import de.mineformers.investiture.allomancy.api.misting.physical.Thug;
import de.mineformers.investiture.allomancy.api.misting.physical.Tineye;
import de.mineformers.investiture.allomancy.api.misting.temporal.Augur;
import de.mineformers.investiture.allomancy.api.misting.temporal.Oracle;
import de.mineformers.investiture.allomancy.api.misting.temporal.Pulser;
import de.mineformers.investiture.allomancy.api.misting.temporal.Slider;
import de.mineformers.investiture.allomancy.impl.misting.mental.RioterImpl;
import de.mineformers.investiture.allomancy.impl.misting.mental.SootherImpl;
import de.mineformers.investiture.allomancy.impl.misting.physical.CoinshotImpl;
import de.mineformers.investiture.allomancy.impl.misting.physical.LurcherImpl;
import de.mineformers.investiture.allomancy.impl.misting.physical.ThugImpl;
import de.mineformers.investiture.allomancy.impl.misting.physical.TineyeImpl;
import de.mineformers.investiture.allomancy.impl.misting.temporal.*;
import de.mineformers.investiture.allomancy.item.MetalItem;
import de.mineformers.investiture.serialisation.Serialisation;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockWorldState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ITickable;
import net.minecraft.world.World;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
 *
 */
@ParametersAreNonnullByDefault
public class AllomancyAPIImpl implements AllomancyAPI
{
    public static final AllomancyAPIImpl INSTANCE = new AllomancyAPIImpl();
    private static final List<Class<?>> INJECTABLE_TYPES = ImmutableList.of(Allomancer.class, Entity.class);

    public static Optional<Allomancer> getAllomancer(Entity player)
    {
        return INSTANCE.toAllomancer(player);
    }

    Map<Class<? extends Misting>, MistingData> factories = new HashMap<>();
    private Map<Class<?>, BiPredicate<?, ?>> equalities = new HashMap<>();
    private Set<Predicate<ItemStack>> metallicItems = new HashSet<>();
    private Set<Predicate<BlockWorldState>> metallicBlocks = new HashSet<>();
    private Set<Predicate<Entity>> metallicEntities = new HashSet<>();
    private Set<MetalMapping> mappings = new HashSet<>();

    private AllomancyAPIImpl()
    {
    }

    public void init()
    {
        registerEquality(ItemStack.class, ItemStack::areItemStacksEqual);

        registerMisting(Coinshot.class, CoinshotImpl::new);
        registerMisting(Lurcher.class, LurcherImpl::new);
        registerMisting(Tineye.class, TineyeImpl::new);
        registerMisting(Thug.class, ThugImpl::new);

        registerMisting(Soother.class, SootherImpl::new);
        registerMisting(Rioter.class, RioterImpl::new);

        registerMisting(Augur.class, AugurImpl::new);
        registerMisting(Oracle.class, OracleImpl::new);
        registerMisting(Pulser.class, PulserImpl::new);
        registerMisting(Slider.class, SliderImpl::new);

        registerOreDictMapping(Metals.IRON, MetalItem.Type.INGOT, false);
        registerOreDictMapping(Metals.GOLD, MetalItem.Type.INGOT, false);
        registerOreDictMapping(Metals.IRON, MetalItem.Type.NUGGET, false);
        registerOreDictMapping(Metals.GOLD, MetalItem.Type.NUGGET, false);

        registerMetallicItem(stack -> !Metals.getMetalStacks(stack).isEmpty());
        registerMetallicItem(stack ->
                             {
                                 Item item = stack.getItem();
                                 Block block = Block.getBlockFromItem(item);
                                 return isMetallic(block.getDefaultState());
                             });

        registerMetallicBlock(s -> s.getBlockState().getMaterial() == Material.IRON || s.getBlockState().getMaterial() == Material.ANVIL);

        registerMetallicEntity(e -> e instanceof EntityItem && isMetallic(((EntityItem) e).getItem()));
    }

    private void registerOreDictMapping(Metal metal, MetalItem.Type type, boolean nbt)
    {
        String oreName = String.format("%s%s", type.name().toLowerCase(), StringUtils.capitalize(metal.id()));
        registerMetalMapping(
            new MetalMapping.OreDict(oreName, metal,
                                     type.conversion, type.purityRange.hasLowerBound() ? type.purityRange.lowerEndpoint() : 0, type.purityRange,
                                     nbt));
    }

    public Optional<Class<? extends Misting>> getMistingType(String identifier)
    {
        return factories.keySet().stream().filter(c -> c.getSimpleName().equalsIgnoreCase(identifier)).findFirst();
    }

    public Collection<String> getMistingNames()
    {
        List<String> result = factories.keySet().stream().map(c -> c.getSimpleName().toLowerCase()).collect(Collectors.toList());
        result.sort(String::compareToIgnoreCase);
        return result;
    }

    @Nonnull
    public Optional<Allomancer> toAllomancer(Entity entity)
    {
        return Optional.ofNullable(entity.getCapability(Capabilities.ALLOMANCER, null));
    }

    @Override
    public <T extends Misting> void registerMisting(Class<T> type, MistingFactory<? extends T> factory)
    {
        factories.put(type, new MistingData(type, factory));
    }

    @Override
    public <T> void registerEquality(Class<T> type, BiPredicate<T, T> predicate)
    {
        equalities.put(type, predicate);
    }

    @Override
    public void registerMetallicItem(Predicate<ItemStack> predicate)
    {
        metallicItems.add(predicate);
    }

    @Override
    public void registerMetallicBlock(Predicate<BlockWorldState> predicate)
    {
        metallicBlocks.add(predicate);
    }

    @Override
    public void registerMetallicEntity(Predicate<Entity> predicate)
    {
        metallicEntities.add(predicate);
    }

    @Nonnull
    @Override
    public Collection<Predicate<ItemStack>> metallicItems()
    {
        return Collections.unmodifiableSet(metallicItems);
    }

    @Nonnull
    @Override
    public Collection<Predicate<BlockWorldState>> metallicBlocks()
    {
        return Collections.unmodifiableSet(metallicBlocks);
    }

    @Nonnull
    @Override
    public Collection<Predicate<Entity>> metallicEntities()
    {
        return Collections.unmodifiableSet(metallicEntities);
    }

    @Override
    public Iterable<SpeedBubble> speedBubbles(World world)
    {
        return SpeedBubbles.from(world);
    }

    @Override
    public Optional<MetalMapping> getMapping(ItemStack stack)
    {
        return mappings.stream().filter(m -> m.matches(stack)).findFirst();
    }

    @Override
    public void registerMetalMapping(MetalMapping mapping)
    {
        mappings.add(mapping);
    }

    @Nullable
    @SuppressWarnings("unchecked")
    <T extends Misting> T instantiate(Class<T> type, Allomancer allomancer, Entity entity)
    {
        MistingData data = factories.get(type);
        if (data == null)
            return null;
        T result = (T) data.factory.create();
        data.inject(result, ImmutableMap.of(Allomancer.class, allomancer,
                                            Entity.class, entity));
        return result;
    }

    public void update(Allomancer allomancer, Entity entity)
    {
        for (Class<? extends Misting> type : allomancer.powers())
        {
            allomancer.as(type).ifPresent(m ->
                                          {
                                              if (allomancer.activePowers().contains(type))
                                              {
                                                  if (entity.world.isRemote ||
                                                      (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()))
                                                  {
                                                      if (m instanceof ITickable)
                                                          ((ITickable) m).update();
                                                  }
                                                  else
                                                  {
                                                      Metal metal = m.baseMetal();
                                                      Set<MetalStack> burned = allomancer.storage().burn(metal, metal.burnRate(), false);
                                                      float available = burned.stream()
                                                                              .reduce(0f, (acc, s) -> acc + s.getQuantity(), (a, b) -> a + b);
                                                      float impurities =
                                                          burned
                                                              .stream()
                                                              .reduce(0f, (acc, s) -> acc + s.getQuantity() * Math.max(0, 0.9f - s.getPurity()),
                                                                      (a, b) -> a + b);
                                                      if (available >= metal.burnRate())
                                                      {
                                                          if (m instanceof ITickable)
                                                              ((ITickable) m).update();
                                                      }
                                                      else
                                                      {
                                                          allomancer.deactivate(type);
                                                      }
                                                      if (impurities > 0)
                                                      {
                                                          metal.applyImpurityEffects(entity, impurities);
                                                      }
                                                  }
                                              }
                                              if (!entity.world.isRemote)
                                                  factories.get(type).companion.write(m, entity);
                                          });
        }
    }

    public void read(Entity entity, Class<? extends Misting> type, byte[] data)
    {
        toAllomancer(entity).map(a -> a.grantPower(type)).ifPresent(m -> factories.get(type).companion.read(m, data));
    }

    @SuppressWarnings("unchecked")
    public <T> boolean equals(T a, T b)
    {
        return (a == b) || ((BiPredicate<T, T>) Optional.ofNullable(equalities.get(a.getClass())).orElse(Objects::equals)).test(a, b);
    }

    static class MistingData
    {
        public final Class<? extends Misting> type;
        private final MistingFactory<?> factory;
        final Collection<Field> injectedFields;
        final AllomancerCompanion companion;

        MistingData(Class<? extends Misting> baseType, MistingFactory<?> factory)
        {
            this.factory = factory;
            type = factory.referenceClass();
            injectedFields = StreamSupport
                .stream(ClassUtils.hierarchy(type, ClassUtils.Interfaces.INCLUDE).spliterator(), false)
                .map(Class::getDeclaredFields)
                .flatMap(Arrays::stream)
                .filter(f -> f.getAnnotation(Inject.class) != null &&
                    INJECTABLE_TYPES.stream().anyMatch(t -> t.isAssignableFrom(f.getType())))
                .collect(Collectors.toList());
            injectedFields.forEach(f -> f.setAccessible(true));
            this.companion = new AllomancerCompanion(type, baseType);
            Serialisation.INSTANCE.registerClass(type, true);
        }

        void inject(Misting instance, Map<Class<?>, Object> values)
        {
            for (Field f : injectedFields)
            {
                values.keySet()
                      .stream()
                      .filter(e -> e.isAssignableFrom(f.getType()))
                      .findFirst()
                      .ifPresent(t ->
                                 {
                                     try
                                     {
                                         f.set(instance, values.get(t));
                                     }
                                     catch (IllegalAccessException e)
                                     {
                                         Throwables.propagate(e);
                                     }
                                 });
            }
        }
    }
}


text:
using namespace xbox::services::game_server_platform;

NAMESPACE_MICROSOFT_XBOX_SERVICES_GAMESERVERPLATFORM_BEGIN

GameVariantSchema::GameVariantSchema(
    _In_ game_variant_schema cppObj
    ) :
    m_cppObj(std::move(cppObj))
{
}

NAMESPACE_MICROSOFT_XBOX_SERVICES_GAMESERVERPLATFORM_END


text:
package leaks.SubBranchRefute;
public class FakeMap {

    private final static Object[] EMPTY_TABLE = new Object[1];
    private int size;
    private int capacity;
    private Object[] table;

    public FakeMap() {
	table = EMPTY_TABLE;
	size = 0;
	capacity = 0;
    }

    public Object put(String i, Object value) {
	if (size < capacity) {
	    foo();
	} else if (size == capacity) {
	    doubleCapacity();
	} else {
	    bar();
	}
	table[size] = value;
	return null;
    }

    private void doubleCapacity() {
	capacity = size * 2;
	table = new Object[capacity];
    }

    public void foo() {

    }

    public void bar() {

    }
}


text:
<!DOCTYPE html>
<html lang="en">
<head>
	<title><?php echo $title; ?></title>
	  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	  <meta name="viewport" content="width=device-width, initial-scale=1">
	  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2, user-scalable=1">
	  <meta name="apple-mobile-web-app-capable" content="yes" />
	  <link rel="icon" type="image/gif" href="<?php echo asset_url() . "imgs/logo.png"?>" />
	  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
	  <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
	  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
	  <link rel="stylesheet" type="text/css" href="<?php echo asset_url() . "css/" . $css;?>">
	  <?php if(isset($additional_css)) {?>
	  	<link rel="stylesheet" type="text/css" href="<?php echo asset_url() . "css/" . $additional_css;?>">
	  <?php }?>
	  <link rel="stylesheet" type="text/css" href="<?php echo asset_url() . "css/bootstrap-social.css";?>">
	  <link rel="stylesheet" type="text/css" href="<?php echo asset_url() . "EasyAutocomplete-1.3.5/easy-autocomplete.min.css"?>"/>
	  <link rel="stylesheet" href="<?php echo asset_url() . "EasyAutocomplete-1.3.5/easy-autocomplete.themes.min.css"?>">
	  <link rel="stylesheet" href="<?php echo asset_url() . "css/resize_autocomplete.css"?>" id="resize_autocomplete">
	  <script src="<?php echo asset_url() . "js/jquery-3.1.1.min.js"?>"></script>
	  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	  <script type="text/javascript" src="<?php echo asset_url() . "EasyAutocomplete-1.3.5/jquery.easy-autocomplete.min.js"?>"></script>

	  <script src="<?php echo asset_url() . "js/home.js";?>"></script>
	  <script src="<?php echo asset_url() . "js/autocomplete.js";?>"></script>

</head>
<body>


text:
require File.expand_path('../base', __FILE__)

class FtLaunchitemTest < Test::Unit::TestCase
  include FunctionalBase

  def test_launch

    pdef = Ruote.process_definition do
      alpha
    end

    @dashboard.register_participant :alpha do |workitem|
      stash[:fields] = workitem.fields
      tracer << 'a'
      nil
    end

    wfid = @dashboard.launch(pdef, 'a' => 0, 'b' => 1)
    wait_for(wfid)

    assert_equal('a', @tracer.to_s)

    @dashboard.context.stash[:fields].delete('__result__')

    assert_not_nil(
      @dashboard.context.stash[:fields].delete('dispatched_at'))

    assert_equal(
      { 'a' => 0, 'b' => 1, 'params' => { 'ref' => 'alpha' } },
      @dashboard.context.stash[:fields])
  end

  # Warning: this test requires rufus-json to have a backend ready.
  #
  def test_launch_and_variables_with_symbol_keys

    pdef = Ruote.define do
      echo '${f} / ${v:v}'
    end

    wfid = @dashboard.launch(pdef, { :f => 'x' }, { :v => 'y' })
    wait_for(wfid)

    assert_equal 'x / y', @tracer.to_s
  end
end


text:
exports.defineAutoTests = function () {
    var fail = function (done) {
        expect(true).toBe(false);
        done();
    },
    succeed = function (done) {
        expect(true).toBe(true);
        done();
    };

    describe('Geolocation (navigator.geolocation)', function () {

        it("geolocation.spec.1 should exist", function () {
            expect(navigator.geolocation).toBeDefined();
        });

        it("geolocation.spec.2 should contain a getCurrentPosition function", function () {
            expect(typeof navigator.geolocation.getCurrentPosition).toBeDefined();
            expect(typeof navigator.geolocation.getCurrentPosition == 'function').toBe(true);
        });

        it("geolocation.spec.3 should contain a watchPosition function", function () {
            expect(typeof navigator.geolocation.watchPosition).toBeDefined();
            expect(typeof navigator.geolocation.watchPosition == 'function').toBe(true);
        });

        it("geolocation.spec.4 should contain a clearWatch function", function () {
            expect(typeof navigator.geolocation.clearWatch).toBeDefined();
            expect(typeof navigator.geolocation.clearWatch == 'function').toBe(true);
        });

    });

    describe('getCurrentPosition method', function () {

        describe('error callback', function () {

            it("geolocation.spec.5 should be called if we set timeout to 0 and maximumAge to a very small number", function (done) {
                navigator.geolocation.getCurrentPosition(
                    fail.bind(null, done),
                    succeed.bind(null, done),
                    {
                        maximumAge: 0,
                        timeout: 0
                    });
            });

        });

        describe('success callback', function () {

            it("geolocation.spec.6 should be called with a Position object", function (done) {
                navigator.geolocation.getCurrentPosition(function (p) {
                    expect(p.coords).toBeDefined();
                    expect(p.timestamp).toBeDefined();
                    done();
                },
                fail.bind(null, done),
                {
                    maximumAge: 300000 // 5 minutes maximum age of cached position
                });
            });

        });

    });

    describe('watchPosition method', function () {

        describe('error callback', function () {

            var errorWatch = null;
            afterEach(function () {
                navigator.geolocation.clearWatch(errorWatch);
            });

            it("geolocation.spec.7 should be called if we set timeout to 0 and maximumAge to a very small number", function (done) {
                errorWatch = navigator.geolocation.watchPosition(
                    fail.bind(null, done),
                    succeed.bind(null, done),
                    {
                        maximumAge: 0,
                        timeout: 0
                    });
            });

        });

        describe('success callback', function () {

            var successWatch = null;
            afterEach(function () {
                navigator.geolocation.clearWatch(successWatch);
            });

            it("geolocation.spec.8 should be called with a Position object", function (done) {

                successWatch = navigator.geolocation.watchPosition(
                    function (p) {
                        expect(p.coords).toBeDefined();
                        expect(p.timestamp).toBeDefined();
                        done();
                    },
                    fail.bind(null, done),
                    {
                        maximumAge: (5 * 60 * 1000) // 5 minutes maximum age of cached position
                    });

            });

        });

    });

};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    var newGeolocation = navigator.geolocation;
    var origGeolocation = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
    if (!origGeolocation) {
        origGeolocation = newGeolocation;
        newGeolocation = null;
    }

    var watchLocationId = null;

    /**
     * Start watching location
     */
    var watchLocation = function (usePlugin) {
        console.log("watchLocation()");
        var geo = usePlugin ? newGeolocation : origGeolocation;
        if (!geo) {
            alert('geolocation object is missing. usePlugin = ' + usePlugin);
            return;
        }

        // Success callback
        var success = function (p) {
            setLocationDetails(p);
        };

        // Fail callback
        var fail = function (e) {
            console.log("watchLocation fail callback with error code " + e);
            stopLocation(geo);
        };

        // Get location
        watchLocationId = geo.watchPosition(success, fail, { enableHighAccuracy: true });
        setLocationStatus("Running");
    };

    /**
     * Stop watching the location
     */
    var stopLocation = function (usePlugin) {
        console.log("stopLocation()");
        var geo = usePlugin ? newGeolocation : origGeolocation;
        if (!geo) {
            alert('geolocation object is missing. usePlugin = ' + usePlugin);
            return;
        }
        setLocationStatus("Stopped");
        if (watchLocationId) {
            geo.clearWatch(watchLocationId);
            watchLocationId = null;
        }
    };

    /**
     * Get current location
     */
    var getLocation = function (usePlugin, opts) {
        console.log("getLocation()");
        var geo = usePlugin ? newGeolocation : origGeolocation;
        if (!geo) {
            alert('geolocation object is missing. usePlugin = ' + usePlugin);
            return;
        }

        // Stop location if running
        stopLocation(geo);

        // Success callback
        var success = function (p) {
            setLocationDetails(p);
            setLocationStatus("Done");
        };

        // Fail callback
        var fail = function (e) {
            console.log("getLocation fail callback with error code " + e.code);
            setLocationStatus("Error: " + e.code);
        };

        setLocationStatus("Retrieving location...");

        // Get location
        geo.getCurrentPosition(success, fail, opts || { enableHighAccuracy: true }); //, {timeout: 10000});

    };

    /**
     * Set location status
     */
    var setLocationStatus = function (status) {
        document.getElementById('location_status').innerHTML = status;
    };
    var setLocationDetails = function (p) {
        var date = (new Date(p.timestamp));
        document.getElementById('latitude').innerHTML = p.coords.latitude;
        document.getElementById('longitude').innerHTML = p.coords.longitude;
        document.getElementById('altitude').innerHTML = p.coords.altitude;
        document.getElementById('accuracy').innerHTML = p.coords.accuracy;
        document.getElementById('heading').innerHTML = p.coords.heading;
        document.getElementById('speed').innerHTML = p.coords.speed;
        document.getElementById('altitude_accuracy').innerHTML = p.coords.altitudeAccuracy;
        document.getElementById('timestamp').innerHTML = date.toDateString() + " " + date.toTimeString();
    }

    /******************************************************************************/

    var location_div = '
' +
            'Status: Stopped' +
            '
',
        latitude = '
' +
            'Latitude:	' +
            ' 	' +
            '(decimal degrees) geographic coordinate [#ref]	' +
            '
',
        longitude = '
' +
            'Longitude:	' +
            ' 	' +
            '(decimal degrees) geographic coordinate [#ref]	' +
            '
',
        altitude = '
' +
            'Altitude:	' +
            ' 	' +
            'null if not supported;
' +
            '(meters) height above the [WGS84] ellipsoid. [#ref]	' +
            '
',
        accuracy = '
' +
            'Accuracy:	' +
            ' 	' +
            '(meters; non-negative; 95% confidence level) the accuracy level of the latitude and longitude coordinates. [#ref]	' +
            '
',
        heading = '
' +
            'Heading:	' +
            ' 	' +
            'null if not supported;
' +
            'NaN if speed == 0;
' +
            '(degrees; 0° ≤ heading < 360°) direction of travel of the hosting device- counting clockwise relative to the true north. [#ref]	' +
            '
',
        speed = '
' +
            'Speed:	' +
            ' 	' +
            'null if not supported;
' +
            '(meters per second; non-negative) magnitude of the horizontal component of the hosting device current velocity. [#ref]	' +
            '
',
        altitude_accuracy = '
' +
            'Altitude Accuracy:	' +
            ' 	' +
            'null if not supported;
(meters; non-negative; 95% confidence level) the accuracy level of the altitude. [#ref]	' +
            '
',
        time = '
' +
            'Time:	' +
            ' 	' +
            '(DOMTimeStamp) when the position was acquired [#ref]	' +
            '
' +
            '
' +
            '
',
        actions =
            '
Use Built-in WebView navigator.geolocation
' +
            '

' +
            'Expected result: Will update all applicable values in status box for current location. Status will read Retrieving Location (may not see this if location is retrieved immediately) then Done.' +
            '

' +
            'Expected result: Will update all applicable values in status box for current location and update as location changes. Status will read Running.' +
            '

' +
            'Expected result: Will stop watching the location so values will not be updated. Status will read Stopped.' +
            '

' +
            'Expected result: Will update location values with a cached position that is up to 30 seconds old. Verify with time value. Status will read Done.' +
            '
Use Cordova Geolocation Plugin
' +
            '

' +
            'Expected result: Will update all applicable values in status box for current location. Status will read Retrieving Location (may not see this if location is retrieved immediately) then Done.' +
            '

' +
            'Expected result: Will update all applicable values in status box for current location and update as location changes. Status will read Running.' +
            '

' +
            'Expected result: Will stop watching the location so values will not be updated. Status will read Stopped.' +
            '

' +
            'Expected result: Will update location values with a cached position that is up to 30 seconds old. Verify with time value. Status will read Done.',
        values_info =
            '
Details about each value are listed below in the status box
',
        note =
            '
Allow use of current location, if prompted
';

    contentEl.innerHTML = values_info + location_div + latitude + longitude + altitude + accuracy + heading + speed
        + altitude_accuracy + time + note + actions;

    createActionButton('Get Location', function () {
        getLocation(false);
    }, 'built-in-getLocation');

    createActionButton('Start Watching Location', function () {
        watchLocation(false);
    }, 'built-in-watchLocation');

    createActionButton('Stop Watching Location', function () {
        stopLocation(false);
    }, 'built-in-stopLocation');

    createActionButton('Get Location Up to 30 Sec Old', function () {
        getLocation(false, { maximumAge: 30000 });
    }, 'built-in-getOld');

    createActionButton('Get Location', function () {
        getLocation(true);
    }, 'cordova-getLocation');

    createActionButton('Start Watching Location', function () {
        watchLocation(true);
    }, 'cordova-watchLocation');

    createActionButton('Stop Watching Location', function () {
        stopLocation(true);
    }, 'cordova-stopLocation');

    createActionButton('Get Location Up to 30 Sec Old', function () {
        getLocation(true, { maximumAge: 30000 });
    }, 'cordova-getOld');
};