text:
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis
{
    using MetadataOrDiagnostic = System.Object;

    /// <summary>
    /// The base class for language specific assembly managers.
    /// </summary>
    /// <typeparam name="TCompilation">Language specific representation for a compilation</typeparam>
    /// <typeparam name="TAssemblySymbol">Language specific representation for an assembly symbol.</typeparam>
    internal abstract partial class CommonReferenceManager<TCompilation, TAssemblySymbol>
        where TCompilation : Compilation
        where TAssemblySymbol : class, IAssemblySymbol
    {
        protected abstract CommonMessageProvider MessageProvider { get; }

        protected abstract AssemblyData CreateAssemblyDataForFile(
            PEAssembly assembly,
            WeakList<IAssemblySymbol> cachedSymbols,
            DocumentationProvider documentationProvider,
            string sourceAssemblySimpleName,
            MetadataImportOptions importOptions,
            bool embedInteropTypes);

        protected abstract AssemblyData CreateAssemblyDataForCompilation(
            CompilationReference compilationReference);

        /// <summary>
        /// Checks if the properties of <paramref name="duplicateReference"/> are compatible with properties of <paramref name="primaryReference"/>.
        /// Reports inconsistencies to the given diagnostic bag.
        /// </summary>
        /// <returns>True if the properties are compatible and hence merged, false if the duplicate reference should not merge it's properties with primary reference.</returns>
        protected abstract bool CheckPropertiesConsistency(MetadataReference primaryReference, MetadataReference duplicateReference, DiagnosticBag diagnostics);

        /// <summary>
        /// Called to compare two weakly named identities with the same name.
        /// </summary>
        protected abstract bool WeakIdentityPropertiesEquivalent(AssemblyIdentity identity1, AssemblyIdentity identity2);

        [DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
        protected struct ResolvedReference
        {
            private readonly MetadataImageKind _kind;
            private readonly int _index;
            private readonly ImmutableArray<string> _aliases;

            public static readonly ResolvedReference Skipped = default(ResolvedReference);

            public ResolvedReference(int index, MetadataImageKind kind, ImmutableArray<string> aliases)
            {
                Debug.Assert(index >= 0);

                _index = index + 1;
                _kind = kind;
                _aliases = aliases;
            }

            public ImmutableArray<string> Aliases
            {
                get
                {
                    Debug.Assert(!_aliases.IsDefault);
                    return _aliases;
                }
            }

            public bool IsSkipped
            {
                get
                {
                    return _index == 0;
                }
            }

            public MetadataImageKind Kind
            {
                get
                {
                    Debug.Assert(!IsSkipped);
                    return _kind;
                }
            }

            public int Index
            {
                get
                {
                    Debug.Assert(!IsSkipped);
                    return _index - 1;
                }
            }

            private string GetDebuggerDisplay()
            {
                return IsSkipped ? "<skipped>" : (_kind == MetadataImageKind.Assembly ? "A[" : "M[") + Index + "]: aliases=" + _aliases.ToString();
            }
        }

        private struct ReferencedAssemblyIdentity
        {
            public readonly AssemblyIdentity Identity;
            public readonly MetadataReference MetadataReference;

            public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference metadataReference)
            {
                Identity = identity;
                MetadataReference = metadataReference;
            }
        }

        /// <summary>
        /// Resolves given metadata references to assemblies and modules.
        /// </summary>
        /// <param name="compilation">The compilation whose references are being resolved.</param>
        /// <param name="references">List where to store resolved references. References from #r directives will follow references passed to the compilation constructor.</param>
        /// <param name="boundReferenceDirectiveMap">Maps #r values to successuflly resolved metadata references. Does not contain values that failed to resolve.</param>
        /// <param name="boundReferenceDirectives">Unique metadata references resolved from #r directives.</param>
        /// <param name="assemblies">List where to store information about resolved assemblies to.</param>
        /// <param name="modules">List where to store information about resolved modules to.</param>
        /// <param name="diagnostics">Diagnostic bag where to report resolution errors.</param>
        /// <returns>
        /// Maps index to <paramref name="references"/> to an index of a resolved assembly or module in <paramref name="assemblies"/> or <paramref name="modules"/>, respectively.
        ///</returns>
        protected ImmutableArray<ResolvedReference> ResolveMetadataReferences(
            TCompilation compilation,
            out ImmutableArray<MetadataReference> references,
            out IDictionary<string, MetadataReference> boundReferenceDirectiveMap,
            out ImmutableArray<MetadataReference> boundReferenceDirectives,
            out ImmutableArray<AssemblyData> assemblies,
            out ImmutableArray<PEModule> modules,
            DiagnosticBag diagnostics)
        {
            // Locations of all #r directives in the order they are listed in the references list.
            ImmutableArray<Location> referenceDirectiveLocations;
            GetCompilationReferences(compilation, diagnostics, out references, out boundReferenceDirectiveMap, out referenceDirectiveLocations);

            // References originating from #r directives precede references supplied as arguments of the compilation.
            int referenceCount = references.Length;
            int referenceDirectiveCount = (referenceDirectiveLocations != null ? referenceDirectiveLocations.Length : 0);
            int externalReferenceCount = referenceCount - referenceDirectiveCount;

            var referenceMap = new ResolvedReference[referenceCount];

            // Maps references that were added to the reference set (i.e. not filtered out as duplicates) to a set of names that
            // can be used to alias these references. Duplicate assemblies contribute their aliases into this set.
            Dictionary<MetadataReference, ArrayBuilder<string>> aliasMap = null;

            // Used to filter out duplicate references that reference the same file (resolve to the same full normalized path).
            var boundReferences = new Dictionary<MetadataReference, MetadataReference>(MetadataReferenceEqualityComparer.Instance);

            // Used to filter out assemblies that have the same strong or weak identity.
            // Maps simple name to a list of full names.
            Dictionary<string, List<ReferencedAssemblyIdentity>> assemblyReferencesBySimpleName = null;

            ArrayBuilder<MetadataReference> uniqueDirectiveReferences = (referenceDirectiveLocations != null) ? ArrayBuilder<MetadataReference>.GetInstance() : null;
            ArrayBuilder<AssemblyData> assembliesBuilder = null;
            ArrayBuilder<PEModule> modulesBuilder = null;

            // When duplicate references with conflicting EmbedInteropTypes flag are encountered,
            // VB uses the flag from the last one, C# reports an error. We need to enumerate in reverse order
            // so that we find the one that matters first.
            for (int referenceIndex = referenceCount - 1; referenceIndex >= 0; referenceIndex--)
            {
                var boundReference = references[referenceIndex];
                if (boundReference == null)
                {
                    continue;
                }

                // add bound reference if it doesn't exist yet, merging aliases:
                MetadataReference existingReference;
                if (boundReferences.TryGetValue(boundReference, out existingReference))
                {
                    // merge properties of compilation-based references if the underlying compilations are the same
                    if ((object)boundReference != existingReference)
                    {
                        MergeReferenceProperties(existingReference, boundReference, diagnostics, ref aliasMap);
                    }

                    continue;
                }

                boundReferences.Add(boundReference, boundReference);

                Location location;
                if (referenceIndex < referenceDirectiveCount)
                {
                    location = referenceDirectiveLocations[referenceIndex];
                    uniqueDirectiveReferences.Add(boundReference);
                }
                else
                {
                    location = Location.None;
                }

                // compilation reference

                var compilationReference = boundReference as CompilationReference;
                if (compilationReference != null)
                {
                    switch (compilationReference.Properties.Kind)
                    {
                    case MetadataImageKind.Assembly:
                        existingReference = TryAddAssembly(
                            compilationReference.Compilation.Assembly.Identity,
                            boundReference,
                            diagnostics,
                            location,
                            ref assemblyReferencesBySimpleName);

                        if (existingReference != null)
                        {
                            MergeReferenceProperties(existingReference, boundReference, diagnostics, ref aliasMap);
                            continue;
                        }

                        // Note, if SourceAssemblySymbol hasn't been created for
                        // compilationAssembly.Compilation yet, we want this to happen
                        // right now. Conveniently, this constructor will trigger creation of the
                        // SourceAssemblySymbol.
                        var asmData = CreateAssemblyDataForCompilation(compilationReference);
                        AddAssembly(asmData, referenceIndex, referenceMap, ref assembliesBuilder);
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(compilationReference.Properties.Kind);
                    }

                    continue;
                }

                // PE reference

                var peReference = (PortableExecutableReference)boundReference;
                Metadata metadata = GetMetadata(peReference, MessageProvider, location, diagnostics);
                Debug.Assert(metadata != null || diagnostics.HasAnyErrors());

                if (metadata != null)
                {
                    Debug.Assert(metadata != null);

                    switch (peReference.Properties.Kind)
                    {
                    case MetadataImageKind.Assembly:
                        var assemblyMetadata = (AssemblyMetadata)metadata;
                        WeakList<IAssemblySymbol> cachedSymbols = assemblyMetadata.CachedSymbols;

                        if (assemblyMetadata.IsValidAssembly())
                        {
                            PEAssembly assembly = assemblyMetadata.GetAssembly();
                            existingReference = TryAddAssembly(
                                assembly.Identity,
                                peReference,
                                diagnostics,
                                location,
                                ref assemblyReferencesBySimpleName);

                            if (existingReference != null)
                            {
                                MergeReferenceProperties(existingReference, boundReference, diagnostics, ref aliasMap);
                                continue;
                            }

                            var asmData = CreateAssemblyDataForFile(
                                assembly,
                                cachedSymbols,
                                peReference.DocumentationProvider,
                                SimpleAssemblyName,
                                compilation.Options.MetadataImportOptions,
                                peReference.Properties.EmbedInteropTypes);

                            AddAssembly(asmData, referenceIndex, referenceMap, ref assembliesBuilder);
                        }
                        else
                        {
                            diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataFileNotAssembly, location, peReference.Display));
                        }

                        // asmData keeps strong ref after this point
                        GC.KeepAlive(assemblyMetadata);
                        break;

                    case MetadataImageKind.Module:
                        var moduleMetadata = (ModuleMetadata)metadata;
                        if (moduleMetadata.Module.IsLinkedModule)
                        {
                            // We don't support netmodules since some checks in the compiler need information from the full PE image
                            // (Machine, Bit32Required, PE image hash).
                            if (!moduleMetadata.Module.IsEntireImageAvailable)
                            {
                                diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_LinkedNetmoduleMetadataMustProvideFullPEImage, location, peReference.Display));
                            }

                            AddModule(moduleMetadata.Module, referenceIndex, referenceMap, ref modulesBuilder);
                        }
                        else
                        {
                            diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataFileNotModule, location, peReference.Display));
                        }
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(peReference.Properties.Kind);
                    }
                }
            }

            if (uniqueDirectiveReferences != null)
            {
                uniqueDirectiveReferences.ReverseContents();
                boundReferenceDirectives = uniqueDirectiveReferences.ToImmutableAndFree();
            }
            else
            {
                boundReferenceDirectives = ImmutableArray<MetadataReference>.Empty;
            }

            for (int i = 0; i < referenceMap.Length; i++)
            {
                if (!referenceMap[i].IsSkipped)
                {
                    int count = referenceMap[i].Kind == MetadataImageKind.Assembly
                        ? ((object)assembliesBuilder == null ? 0 : assembliesBuilder.Count)
                        : ((object)modulesBuilder == null ? 0 : modulesBuilder.Count);
                    int reversedIndex = count - 1 - referenceMap[i].Index;
                    referenceMap[i] = new ResolvedReference(reversedIndex, referenceMap[i].Kind, GetAliases(references[i], aliasMap));
                }
            }

            if (assembliesBuilder == null)
            {
                assemblies = ImmutableArray<AssemblyData>.Empty;
            }
            else
            {
                assembliesBuilder.ReverseContents();
                assemblies = assembliesBuilder.ToImmutableAndFree();
            }

            if (modulesBuilder == null)
            {
                modules = ImmutableArray<PEModule>.Empty;
            }
            else
            {
                modulesBuilder.ReverseContents();
                modules = modulesBuilder.ToImmutableAndFree();
            }

            return ImmutableArray.CreateRange(referenceMap);
        }

        private static ImmutableArray<string> GetAliases(MetadataReference reference, Dictionary<MetadataReference, ArrayBuilder<string>> aliasMap)
        {
            ArrayBuilder<string> aliases;
            if (aliasMap != null && aliasMap.TryGetValue(reference, out aliases))
            {
                return aliases.ToImmutableAndFree();
            }

            return reference.Properties.Aliases;
        }

        /// <summary>
        /// Creates or gets metadata for PE reference.
        /// </summary>
        /// <remarks>
        /// If any of the following exceptions: <see cref="BadImageFormatException"/>, <see cref="FileNotFoundException"/>, <see cref="IOException"/>,
        /// are thrown while reading the metadata file, the exception is caught and an appropriate diagnostic stored in <paramref name="diagnostics"/>.
        /// </remarks>
        private Metadata GetMetadata(PortableExecutableReference peReference, CommonMessageProvider messageProvider, Location location, DiagnosticBag diagnostics)
        {
            Metadata existingMetadata;

            lock (ObservedMetadata)
            {
                if (TryGetObservedMetadata(peReference, diagnostics, out existingMetadata))
                {
                    return existingMetadata;
                }
            }

            Metadata newMetadata = null;
            Diagnostic newDiagnostic = null;
            try
            {
                newMetadata = peReference.GetMetadata();

                // make sure basic structure of the PE image is valid:
                var assemblyMetadata = newMetadata as AssemblyMetadata;
                if (assemblyMetadata != null)
                {
                    bool dummy = assemblyMetadata.IsValidAssembly();
                }
                else
                {
                    bool dummy = ((ModuleMetadata)newMetadata).Module.IsLinkedModule;
                }
            }
            catch (Exception e) when (e is BadImageFormatException || e is IOException)
            {
                newDiagnostic = PortableExecutableReference.ExceptionToDiagnostic(e, messageProvider, location, peReference.Display, peReference.Properties.Kind);
                newMetadata = null;
            }

            lock (ObservedMetadata)
            {
                if (TryGetObservedMetadata(peReference, diagnostics, out existingMetadata))
                {
                    return existingMetadata;
                }

                if (newDiagnostic != null)
                {
                    diagnostics.Add(newDiagnostic);
                }

                ObservedMetadata.Add(peReference, (MetadataOrDiagnostic)newMetadata ?? newDiagnostic);
                return newMetadata;
            }
        }

        private bool TryGetObservedMetadata(PortableExecutableReference peReference, DiagnosticBag diagnostics, out Metadata metadata)
        {
            MetadataOrDiagnostic existing;
            if (ObservedMetadata.TryGetValue(peReference, out existing))
            {
                Debug.Assert(existing is Metadata || existing is Diagnostic);

                metadata = existing as Metadata;
                if (metadata == null)
                {
                    diagnostics.Add((Diagnostic)existing);
                }

                return true;
            }

            metadata = null;
            return false;
        }

        /// <summary>
        /// Determines whether references are the same. Compilation references are the same if they refer to the same compilation.
        /// Otherwise, references are represented by their object identities.
        /// </summary>
        internal sealed class MetadataReferenceEqualityComparer : IEqualityComparer<MetadataReference>
        {
            internal static readonly MetadataReferenceEqualityComparer Instance = new MetadataReferenceEqualityComparer();

            public bool Equals(MetadataReference x, MetadataReference y)
            {
                if (ReferenceEquals(x, y))
                {
                    return true;
                }

                var cx = x as CompilationReference;
                if (cx != null)
                {
                    var cy = y as CompilationReference;
                    if (cy != null)
                    {
                        return (object)cx.Compilation == cy.Compilation;
                    }
                }

                return false;
            }

            public int GetHashCode(MetadataReference reference)
            {
                var compilationReference = reference as CompilationReference;
                if (compilationReference != null)
                {
                    return RuntimeHelpers.GetHashCode(compilationReference.Compilation);
                }

                return RuntimeHelpers.GetHashCode(reference);
            }
        }

        /// <summary>
        /// Merges aliases of the first observed reference (<paramref name="primaryReference"/>) with aliases specified for an equivalent reference (<paramref name="newReference"/>).
        /// Empty alias list is considered to be the same as a list containing "global", since in both cases C# allows unqualified access to the symbols.
        /// </summary>
        private void MergeReferenceProperties(MetadataReference primaryReference, MetadataReference newReference, DiagnosticBag diagnostics, ref Dictionary<MetadataReference, ArrayBuilder<string>> aliasMap)
        {
            if (!CheckPropertiesConsistency(newReference, primaryReference, diagnostics))
            {
                return;
            }

            if (aliasMap == null)
            {
                aliasMap = new Dictionary<MetadataReference, ArrayBuilder<string>>();
            }

            ArrayBuilder<string> aliases;
            if (!aliasMap.TryGetValue(primaryReference, out aliases))
            {
                aliases = ArrayBuilder<string>.GetInstance();
                aliasMap.Add(primaryReference, aliases);

                if (primaryReference.Properties.Aliases.IsEmpty)
                {
                    aliases.Add(MetadataReferenceProperties.GlobalAlias);
                }
                else
                {
                    aliases.AddRange(primaryReference.Properties.Aliases);
                }
            }

            // we could avoid duplicates but there is no need to do so:
            if (newReference.Properties.Aliases.IsEmpty)
            {
                aliases.Add(MetadataReferenceProperties.GlobalAlias);
            }
            else
            {
                aliases.AddRange(newReference.Properties.Aliases);
            }
        }

        /// <remarks>
        /// Caller is responsible for freeing any allocated ArrayBuilders.
        /// </remarks>
        private static void AddAssembly(AssemblyData data, int referenceIndex, ResolvedReference[] referenceMap, ref ArrayBuilder<AssemblyData> assemblies)
        {
            if (assemblies == null)
            {
                assemblies = ArrayBuilder<AssemblyData>.GetInstance();
            }

            referenceMap[referenceIndex] = new ResolvedReference(assemblies.Count, MetadataImageKind.Assembly, default(ImmutableArray<string>));
            assemblies.Add(data);
        }

        /// <remarks>
        /// Caller is responsible for freeing any allocated ArrayBuilders.
        /// </remarks>
        private static void AddModule(PEModule module, int referenceIndex, ResolvedReference[] referenceMap, ref ArrayBuilder<PEModule> modules)
        {
            if (modules == null)
            {
                modules = ArrayBuilder<PEModule>.GetInstance();
            }

            referenceMap[referenceIndex] = new ResolvedReference(modules.Count, MetadataImageKind.Module, default(ImmutableArray<string>));
            modules.Add(module);
        }

        // Returns null if an assembly of an equivalent identity has not been added previously, otherwise returns the reference that added it.
        // - Both assembly names are strong (have keys) and are either equal or FX unified
        // - Both assembly names are weak (no keys) and have the same simple name.
        private MetadataReference TryAddAssembly(AssemblyIdentity identity, MetadataReference boundReference, DiagnosticBag diagnostics, Location location,
            ref Dictionary<string, List<ReferencedAssemblyIdentity>> referencesBySimpleName)
        {
            if (referencesBySimpleName == null)
            {
                referencesBySimpleName = new Dictionary<string, List<ReferencedAssemblyIdentity>>(StringComparer.OrdinalIgnoreCase);
            }

            List<ReferencedAssemblyIdentity> sameSimpleNameIdentities;
            string simpleName = identity.Name;
            if (!referencesBySimpleName.TryGetValue(simpleName, out sameSimpleNameIdentities))
            {
                referencesBySimpleName.Add(simpleName, new List<ReferencedAssemblyIdentity> { new ReferencedAssemblyIdentity(identity, boundReference) });
                return null;
            }

            ReferencedAssemblyIdentity equivalent = default(ReferencedAssemblyIdentity);
            if (identity.IsStrongName)
            {
                foreach (var other in sameSimpleNameIdentities)
                {
                    // only compare strong with strong (weak is never equivalent to strong and vice versa)
                    if (other.Identity.IsStrongName && IdentityComparer.ReferenceMatchesDefinition(identity, other.Identity))
                    {
                        equivalent = other;
                        break;
                    }
                }
            }
            else
            {
                foreach (var other in sameSimpleNameIdentities)
                {
                    // only compare weak with weak
                    if (!other.Identity.IsStrongName && WeakIdentityPropertiesEquivalent(identity, other.Identity))
                    {
                        equivalent = other;
                        break;
                    }
                }
            }

            if (equivalent.Identity == null)
            {
                sameSimpleNameIdentities.Add(new ReferencedAssemblyIdentity(identity, boundReference));
                return null;
            }

            // equivalent found - ignore and/or report an error:

            if (identity.IsStrongName)
            {
                Debug.Assert(equivalent.Identity.IsStrongName);

                // versions migth have been unified for a Framework assembly:
                if (identity != equivalent.Identity)
                {
                    // Dev12 C# reports an error
                    // Dev12 VB keeps both references in the compilation and reports an ambiguity error when a symbol is used.
                    // BREAKING CHANGE in VB: we report an error for both languages

                    // Multiple assemblies with equivalent identity have been imported: '{0}' and '{1}'. Remove one of the duplicate references.
                    MessageProvider.ReportDuplicateMetadataReferenceStrong(diagnostics, location, boundReference, identity, equivalent.MetadataReference, equivalent.Identity);
                }
                // If the versions match exactly we ignore duplicates w/o reporting errors while
                // Dev12 C# reports:
                //   error CS1703: An assembly with the same identity '{0}' has already been imported. Try removing one of the duplicate references.
                // Dev12 VB reports:
                //   Fatal error BC2000 : compiler initialization failed unexpectedly: Project already has a reference to assembly System.
                //   A second reference to 'D:\Temp\System.dll' cannot be added.
            }
            else
            {
                Debug.Assert(!equivalent.Identity.IsStrongName);

                // Dev12 reports an error for all weak-named assemblies, even if the versions are the same.
                // We treat assemblies with the same name and version equal even if they don't have a strong name.
                // This change allows us to de-duplicate #r references based on identities rather than full paths,
                // and is closer to platforms that don't support strong names and consider name and version enough
                // to identify an assembly. An identity without version is considered to have version 0.0.0.0.

                if (identity != equivalent.Identity)
                {
                    MessageProvider.ReportDuplicateMetadataReferenceWeak(diagnostics, location, boundReference, identity, equivalent.MetadataReference, equivalent.Identity);
                }
            }

            Debug.Assert(equivalent.MetadataReference != null);
            return equivalent.MetadataReference;
        }

        protected void GetCompilationReferences(
            TCompilation compilation,
            DiagnosticBag diagnostics,
            out ImmutableArray<MetadataReference> references,
            out IDictionary<string, MetadataReference> boundReferenceDirectives,
            out ImmutableArray<Location> referenceDirectiveLocations)
        {
            boundReferenceDirectives = null;

            ArrayBuilder<MetadataReference> referencesBuilder = ArrayBuilder<MetadataReference>.GetInstance();
            ArrayBuilder<Location> referenceDirectiveLocationsBuilder = null;

            try
            {
                foreach (var referenceDirective in compilation.ReferenceDirectives)
                {
                    if (compilation.Options.MetadataReferenceResolver == null)
                    {
                        diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataReferencesNotSupported, referenceDirective.Location));
                        break;
                    }

                    // we already successfully bound #r with the same value:
                    if (boundReferenceDirectives != null && boundReferenceDirectives.ContainsKey(referenceDirective.File))
                    {
                        continue;
                    }

                    MetadataReference boundReference = ResolveReferenceDirective(referenceDirective.File, referenceDirective.Location, compilation);
                    if (boundReference == null)
                    {
                        diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataFileNotFound, referenceDirective.Location, referenceDirective.File));
                        continue;
                    }

                    if (boundReferenceDirectives == null)
                    {
                        boundReferenceDirectives = new Dictionary<string, MetadataReference>();
                        referenceDirectiveLocationsBuilder = ArrayBuilder<Location>.GetInstance();
                    }

                    referencesBuilder.Add(boundReference);
                    referenceDirectiveLocationsBuilder.Add(referenceDirective.Location);
                    boundReferenceDirectives.Add(referenceDirective.File, boundReference);
                }

                // add external reference at the end, so that they are processed first:
                referencesBuilder.AddRange(compilation.ExternalReferences);

                if (boundReferenceDirectives == null)
                {
                    // no directive references resolved successfully:
                    boundReferenceDirectives = SpecializedCollections.EmptyDictionary<string, MetadataReference>();
                }

                references = referencesBuilder.ToImmutable();
                referenceDirectiveLocations = referenceDirectiveLocationsBuilder == null ? ImmutableArray<Location>.Empty : referenceDirectiveLocationsBuilder.ToImmutableAndFree();
            }
            finally
            {
                // Put this in a finally because we have tests that (intentionally) cause ResolveReferenceDirective to throw and
                // we don't want to clutter the test output with leak reports.
                referencesBuilder.Free();
            }
        }

        /// <summary>
        /// For each given directive return a bound PE reference, or null if the binding fails.
        /// </summary>
        private PortableExecutableReference ResolveReferenceDirective(string reference, Location location, TCompilation compilation)
        {
            var tree = location.SourceTree;
            string basePath = (tree != null && tree.FilePath.Length > 0) ? tree.FilePath : null;

            // checked earlier:
            Debug.Assert(compilation.Options.MetadataReferenceResolver != null);

            var references = compilation.Options.MetadataReferenceResolver.ResolveReference(reference, basePath, MetadataReferenceProperties.Assembly);
            if (references.IsDefaultOrEmpty)
            {
                return null;
            }

            if (references.Length > 1)
            {
                // TODO: implement
                throw new NotSupportedException();
            }

            return references[0];
        }

        internal static AssemblyReferenceBinding[] ResolveReferencedAssemblies(
            ImmutableArray<AssemblyIdentity> references,
            ImmutableArray<AssemblyData> definitions,
            AssemblyIdentityComparer assemblyIdentityComparer,
            bool okToResolveAgainstCompilationBeingCreated)
        {
            var boundReferences = new AssemblyReferenceBinding[references.Length];
            for (int j = 0; j < references.Length; j++)
            {
                boundReferences[j] = ResolveReferencedAssembly(references[j], definitions, assemblyIdentityComparer, okToResolveAgainstCompilationBeingCreated);
            }

            return boundReferences;
        }

        /// <summary>
        /// Used to match AssemblyRef with AssemblyDef.
        /// </summary>
        /// <param name="definitions">Array of definition identities to match against.</param>
        /// <param name="reference">Reference identity to resolve.</param>
        /// <param name="assemblyIdentityComparer">Assembly identity comparer.</param>
        /// <param name="okToResolveAgainstCompilationBeingCreated"> Is it Ok to resolve reference against the compilation we are creating?</param>
        /// <returns>
        /// Returns an index the reference is bound.
        /// </returns>
        internal static AssemblyReferenceBinding ResolveReferencedAssembly(
            AssemblyIdentity reference,
            ImmutableArray<AssemblyData> definitions,
            AssemblyIdentityComparer assemblyIdentityComparer,
            bool okToResolveAgainstCompilationBeingCreated)
        {
            // Dev11 C# compiler allows the versions to not match exactly, assuming that a newer library may be used instead of an older version.
            // For a given reference it finds a definition with the lowest version that is higher then or equal to the reference version.
            // If match.Version != reference.Version a warning is reported.

            // definition with the lowest version higher than reference version, unless exact version found
            int minHigherVersionDefinition = -1;
            int maxLowerVersionDefinition = -1;

            // NB: Start at 1, since we checked 0 above.
            const int definitionOffset = 1;
            for (int i = definitionOffset; i < definitions.Length; i++)
            {
                AssemblyIdentity definition = definitions[i].Identity;

                switch (assemblyIdentityComparer.Compare(reference, definition))
                {
                case AssemblyIdentityComparer.ComparisonResult.NotEquivalent:
                    continue;

                case AssemblyIdentityComparer.ComparisonResult.Equivalent:
                    return new AssemblyReferenceBinding(reference, i);

                case AssemblyIdentityComparer.ComparisonResult.EquivalentIgnoringVersion:
                    if (reference.Version < definition.Version)
                    {
                        // Refers to an older assembly than we have
                        if (minHigherVersionDefinition == -1 || definition.Version < definitions[minHigherVersionDefinition].Identity.Version)
                        {
                            minHigherVersionDefinition = i;
                        }
                    }
                    else
                    {
                        Debug.Assert(reference.Version > definition.Version);

                        // Refers to a newer assembly than we have
                        if (maxLowerVersionDefinition == -1 || definition.Version > definitions[maxLowerVersionDefinition].Identity.Version)
                        {
                            maxLowerVersionDefinition = i;
                        }
                    }

                    continue;
                }
            }

            // we haven't found definition that matches the reference

            if (minHigherVersionDefinition != -1)
            {
                return new AssemblyReferenceBinding(reference, minHigherVersionDefinition, versionDifference: +1);
            }

            if (maxLowerVersionDefinition != -1)
            {
                return new AssemblyReferenceBinding(reference, maxLowerVersionDefinition, versionDifference: -1);
            }

            // Handle cases where Windows.winmd is a runtime substitute for a
            // reference to a compile-time winmd. This is for scenarios such as a
            // debugger EE which constructs a compilation from the modules of
            // the running process where Windows.winmd loaded at runtime is a
            // substitute for a collection of Windows.*.winmd compile-time references.
            if (reference.IsWindowsComponent())
            {
                for (int i = definitionOffset; i < definitions.Length; i++)
                {
                    if (IsWindowsRuntime(definitions[i]))
                    {
                        return new AssemblyReferenceBinding(reference, i);
                    }
                }
            }

            // As in the native compiler (see IMPORTER::MapAssemblyRefToAid), we compare against the
            // compilation (i.e. source) assembly as a last resort.  We follow the native approach of
            // skipping the public key comparison since we have yet to compute it.
            if (okToResolveAgainstCompilationBeingCreated &&
                AssemblyIdentityComparer.SimpleNameComparer.Equals(reference.Name, definitions[0].Identity.Name))
            {
                Debug.Assert(definitions[0].Identity.PublicKeyToken.IsEmpty);
                return new AssemblyReferenceBinding(reference, 0);
            }

            return new AssemblyReferenceBinding(reference);
        }

        private static bool IsWindowsRuntime(AssemblyData definition)
        {
            if (!definition.Identity.IsWindowsRuntime())
            {
                return false;
            }
            int majorVersion;
            int minorVersion;
            return definition.GetWinMdVersion(out majorVersion, out minorVersion) &&
                (majorVersion == 1) &&
                (minorVersion >= 4);
        }
    }
}


text:
const env         = process.env.DAKDAK_ENV || 'development';
const config      = require(`./envs/${env}.js`);

console.log(`Configs fetched with env "${env}"`);

config.env = env;

module.exports = config;

redpajama_set_name: RedPajamaGithub


text:
//==============================================================================
// Variation of pencil
// Free form loop
// I plan to be abble to add or remove regions from the loop with multiple strokes.
// It will be a state, just like the pencil widget is a state.

(function () {
    // Depends on the CIRCLE widget
    "use strict";

    var DRAWING = 0;
    var ACTIVE = 1;
    var WAITING = 2;

    function LassoWidget (layer, newFlag) {
        if (layer == null) {
            return;
        }

        // Keep track of annotation created by students without edit
        // permission.
        this.UserNoteFlag = ! SA.Edit;
        this.Type = "lasso";

        var self = this;
        this.Dialog = new SAM.Dialog(function () {self.DialogApplyCallback();});
        // Customize dialog for a lasso.
        this.Dialog.Title.text('Lasso Annotation Editor');
        this.Dialog.Body.css({'margin':'1em 2em'});
        // Color
        this.Dialog.ColorDiv =
            $('<div>')
            .appendTo(this.Dialog.Body)
            .addClass("sa-view-annotation-modal-div");
        this.Dialog.ColorLabel =
            $('<div>')
            .appendTo(this.Dialog.ColorDiv)
            .text("Color:")
            .addClass("sa-view-annotation-modal-input-label");
        this.Dialog.ColorInput =
            $('<input type="color">')
            .appendTo(this.Dialog.ColorDiv)
            .val('#30ff00')
            .addClass("sa-view-annotation-modal-input");

        // Line Width
        this.Dialog.LineWidthDiv =
            $('<div>')
            .appendTo(this.Dialog.Body)
            .addClass("sa-view-annotation-modal-div");
        this.Dialog.LineWidthLabel =
            $('<div>')
            .appendTo(this.Dialog.LineWidthDiv)
            .text("Line Width:")
            .addClass("sa-view-annotation-modal-input-label");
        this.Dialog.LineWidthInput =
            $('<input type="number">')
            .appendTo(this.Dialog.LineWidthDiv)
            .addClass("sa-view-annotation-modal-input")
            .keypress(function(event) { return event.keyCode != 13; });

        // Area
        this.Dialog.AreaDiv =
            $('<div>')
            .appendTo(this.Dialog.Body)
            .addClass("sa-view-annotation-modal-div");
        this.Dialog.AreaLabel =
            $('<div>')
            .appendTo(this.Dialog.AreaDiv)
            .text("Area:")
            .addClass("sa-view-annotation-modal-input-label");
        this.Dialog.Area =
            $('<div>')
            .appendTo(this.Dialog.AreaDiv)
            .addClass("sa-view-annotation-modal-input");

        // Get default properties.
        if (localStorage.LassoWidgetDefaults) {
            var defaults = JSON.parse(localStorage.LassoWidgetDefaults);
            if (defaults.Color) {
                this.Dialog.ColorInput.val(SAM.ConvertColorToHex(defaults.Color));
            }
            if (defaults.LineWidth) {
                this.Dialog.LineWidthInput.val(defaults.LineWidth);
            }
        }

        this.Layer = layer;
        this.Popup = new SAM.WidgetPopup(this);
        this.Layer.AddWidget(this);

        var self = this;

        this.Loop = new SAM.Polyline();
        this.Loop.OutlineColor = [0.0, 0.0, 0.0];
        this.Loop.SetOutlineColor(this.Dialog.ColorInput.val());
        this.Loop.FixedSize = false;
        this.Loop.LineWidth = 0;
        this.Loop.Closed = true;
        this.Stroke = false;

        this.ActiveCenter = [0,0];

        if ( newFlag) {
            this.SetStateToDrawing();
        } else {
            this.State = WAITING;
        }
    }

    LassoWidget.prototype.Draw = function(view) {
        this.Loop.Draw(view);
        if (this.Stroke) {
            this.Stroke.Draw(view);
        }
    }

    LassoWidget.prototype.Serialize = function() {
        var obj = new Object();
        obj.type = "lasso";
        obj.user_note_flag = this.UserNoteFlag;
        obj.outlinecolor = this.Loop.OutlineColor;
        obj.linewidth = this.Loop.GetLineWidth();
        obj.points = [];
        for (var j = 0; j < this.Loop.Points.length; ++j) {
            obj.points.push([this.Loop.Points[j][0], this.Loop.Points[j][1]]);
        }
        obj.closedloop = true;

        return obj;
    }

    // Load a widget from a json object (origin MongoDB).
    LassoWidget.prototype.Load = function(obj) {
        this.UserNoteFlag = obj.user_note_flag;
        if (obj.outlinecolor != undefined) {
            this.Loop.OutlineColor[0] = parseFloat(obj.outlinecolor[0]);
            this.Loop.OutlineColor[1] = parseFloat(obj.outlinecolor[1]);
            this.Loop.OutlineColor[2] = parseFloat(obj.outlinecolor[2]);
            // will never happen
            //if (this.Stroke) {
            //    this.Stroke.OutlineColor = this.Loop.OutlineColor;
            //}
        }
        if (obj.outlinewidth != undefined) {
            this.Loop.LineWidth = obj.linewidth;
        }
        var points = [];
        if ( obj.points != undefined) {
            points = obj.points;
        }
        if ( obj.shape != undefined) {
            points = obj.shapes[0];
        }

        for(var n=0; n < points.length; n++){
            this.Loop.Points[n] = [parseFloat(points[n][0]),
                                   parseFloat(points[n][1])];
        }
        this.ComputeActiveCenter();
        this.Loop.UpdateBuffers(this.Layer.AnnotationView);
    }

    LassoWidget.prototype.HandleMouseWheel = function(event) {
        if ( this.State == DRAWING ||
             this.State == ACTIVE) {
            if ( ! this.Loop) { return true; }
            var tmp = 0;

            if (event.deltaY) {
                tmp = event.deltaY;
            } else if (event.wheelDelta) {
                tmp = event.wheelDelta;
            }

            var minWidth = 1.0 / this.Layer.GetPixelsPerUnit();

            // Wheel event seems to be in increments of 3.
            // depreciated mousewheel had increments of 120....
            var lineWidth = this.Loop.GetLineWidth();
            lineWidth = lineWidth || minWidth;
            if (tmp > 0) {
                lineWidth *= 1.1;
            } else if (tmp < 0) {
                lineWidth /= 1.1;
            }
            if (lineWidth <= minWidth) {
                lineWidth = 0.0;
            }
            this.Dialog.LineWidthInput.val(lineWidth);
            this.Loop.SetLineWidth(lineWidth);
            this.Loop.UpdateBuffers(this.Layer.AnnotationView);

            this.Layer.EventuallyDraw();
            return false;
        }
        return true;
    }

    LassoWidget.prototype.Deactivate = function() {
        this.Popup.StartHideTimer();
        this.Layer.DeactivateWidget(this);
        this.State = WAITING;
        this.Loop.SetActive(false);
        if (this.Stroke) {
            this.Stroke.SetActive(false);
        }
        if (this.DeactivateCallback) {
            this.DeactivateCallback();
        }
        this.Layer.EventuallyDraw();
    }

    LassoWidget.prototype.HandleKeyDown = function(event) {
        if ( this.State == DRAWING) {
            // escape key (or space or enter) to turn off drawing
            if (event.keyCode == 27 || event.keyCode == 32 || event.keyCode == 13) {
                this.Deactivate();
                return false;
            }
        }
    }

    LassoWidget.prototype.HandleMouseDown = function(event) {
        var x = event.offsetX;
        var y = event.offsetY;

        if (event.which == 1) {
            // Start drawing.
            // Stroke is a temporary line for interaction.
            // When interaction stops, it is converted/merged with loop.
            this.Stroke = new SAM.Polyline();
            this.Stroke.OutlineColor = [0.0, 0.0, 0.0];
            this.Stroke.SetOutlineColor(this.Loop.OutlineColor);
            //this.Stroke.SetOutlineColor(this.Dialog.ColorInput.val());
            this.Stroke.FixedSize = false;
            this.Stroke.LineWidth = 0;

            var pt = this.Layer.GetCamera().ConvertPointViewerToWorld(x,y);
            this.Stroke.Points = [];
            this.Stroke.Points.push([pt[0], pt[1]]); // avoid same reference.
            return false;
        }
        return true;
    }

    LassoWidget.prototype.HandleMouseUp = function(event) {
        // Middle mouse deactivates the widget.
        if (event.which == 2) {
            // Middle mouse was pressed.
            this.Deactivate();
        }

        // A stroke has just been finished.
        if (event.which == 1 && this.State == DRAWING) {
            var spacing = this.Layer.GetCamera().GetSpacing();
            //this.Decimate(this.Stroke, spacing);
            this.Stroke.Decimate(spacing);
            if (this.Loop && this.Loop.Points.length > 0) {
                this.CombineStroke();
            } else {
                this.Stroke.Closed = true;
                this.Stroke.UpdateBuffers(this.Layer.AnnotationView);
                this.Loop = this.Stroke;
                this.Stroke = false;
            }
            this.ComputeActiveCenter();
            this.Layer.EventuallyDraw();

            if (this.UserNoteFlag && SA.notesWidget){SA.notesWidget.EventuallySaveUserNote();}
            if (window.SA) {SA.RecordState();}
        }
        return false;
    }

    LassoWidget.prototype.HandleDoubleClick = function(event) {
        if (this.State == DRAWING) {
            this.Deactivate();
            return false;
        }
        if (this.State == ACTIVE) {
            this.SetStateToDrawing();
            return false;
        }
        return true;
    }

    LassoWidget.prototype.SetStateToDrawing = function() {
        this.State = DRAWING;
        // When drawing, the cursor is enough indication.
        // We keep the lines the normal color. Yellow is too hard to see.
        this.Loop.SetActive(false);
        this.Popup.Hide();
        this.Layer.GetCanvasDiv().css(
            {'cursor':'url('+SAM.ImagePathUrl+'select_lasso.png) 5 30,crosshair'});
        this.Layer.EventuallyDraw();
    }

    LassoWidget.prototype.HandleMouseMove = function(event) {
        var x = event.offsetX;
        var y = event.offsetY;

        if (event.which == 1 && this.State == DRAWING) {
            var shape = this.Stroke;
            var pt = this.Layer.GetCamera().ConvertPointViewerToWorld(x,y);
            shape.Points.push([pt[0], pt[1]]); // avoid same reference.
            shape.UpdateBuffers(this.Layer.AnnotationView);
            if (SA.notesWidget && ! this.UserNoteFlag) {SA.notesWidget.MarkAsModified();} // hack
            if (this.UserNoteFlag && SA.notesWidget){SA.notesWidget.EventuallySaveUserNote();}
            this.Layer.EventuallyDraw();
            return false;
        }

        if (this.State == ACTIVE &&
            event.which == 0) {
            // Deactivate
            this.SetActive(this.CheckActive(event));
            return false;
        }
        return true;
    }

    LassoWidget.prototype.ComputeActiveCenter = function() {
        var count = 0;
        var sx = 0.0;
        var sy = 0.0;
        var shape = this.Loop;
        var points = [];
        for (var j = 0; j < shape.Points.length; ++j) {
            sx += shape.Points[j][0];
            sy += shape.Points[j][1];
        }

        this.ActiveCenter[0] = sx / shape.Points.length;
        this.ActiveCenter[1] = sy / shape.Points.length;
    }

    // This also shows the popup if it is not visible already.
    LassoWidget.prototype.PlacePopup = function () {
        var pt = this.Loop.FindPopupPoint(this.Layer.GetCamera());
        pt = this.Layer.GetCamera().ConvertPointWorldToViewer(pt[0], pt[1]);

        pt[0] += 20;
        pt[1] -= 10;

        this.Popup.Show(pt[0],pt[1]);
    }

    // Just returns whether the widget thinks it should be active.
    // Layer is responsible for seting it to active.
    LassoWidget.prototype.CheckActive = function(event) {
        if (this.State == DRAWING) { return; }

        var x = event.offsetX;
        var y = event.offsetY;
        var pt = this.Layer.GetCamera().ConvertPointViewerToWorld(x,y);

        var width = this.Loop.GetLineWidth() / 2;
        // Tolerance: 5 screen pixels.
        var minWidth = 10.0 / this.Layer.GetPixelsPerUnit();
        if (width < minWidth) { width = minWidth;}

        if (this.Loop.PointOnShape(pt, width)) {
            return true;
        } else {
            return false;
        }
    }

    LassoWidget.prototype.GetActive = function() {
        return this.State != WAITING;
    }

    // Setting to active always puts state into "active".
    // It can move to other states and stay active.
    LassoWidget.prototype.SetActive = function(flag) {
        if (flag) {
            if (this.State == WAITING ) {
                this.State = ACTIVE;
                this.Loop.SetActive(true);
                this.PlacePopup();
                this.Layer.EventuallyDraw();
            }
        } else {
            if (this.State != WAITING) {
                this.Deactivate();
                this.Layer.DeactivateWidget(this);
            }
        }
        this.Layer.EventuallyDraw();
    }

    // It would be nice to put this as a superclass method, or call the
    // layer.RemoveWidget method instead.
    LassoWidget.prototype.RemoveFromLayer = function() {
        if (this.Layer) {
            this.RemoveWidget(this);
        }
    }

    // Can we bind the dialog apply callback to an objects method?
    LassoWidget.prototype.ShowPropertiesDialog = function () {
        this.Dialog.ColorInput.val(SAM.ConvertColorToHex(this.Loop.OutlineColor));
        this.Dialog.LineWidthInput.val((this.Loop.LineWidth).toFixed(2));

        var area = this.ComputeArea();
        var areaString = "" + area.toFixed(2);
        if (this.Loop.FixedSize) {
            areaString += " pixels^2";
        } else {
            areaString += " units^2";
        }
        this.Dialog.Area.text(areaString);
        this.Dialog.Show(true);
    }

    LassoWidget.prototype.DialogApplyCallback = function() {
        var hexcolor = this.Dialog.ColorInput.val();
        this.Loop.SetOutlineColor(hexcolor);
        this.Loop.LineWidth = parseFloat(this.Dialog.LineWidthInput.val());
        this.Loop.UpdateBuffers(this.Layer.AnnotationView);
        this.SetActive(false);
        if (window.SA) {SA.RecordState();}
        this.Layer.EventuallyDraw();

        localStorage.LassoWidgetDefaults = JSON.stringify({Color: hexcolor, LineWidth: this.Loop.LineWidth});
        if (SAM.NotesWidget && ! this.UserNoteFlag) {SAM.NotesWidget.MarkAsModified();} // hack
        if (this.UserNoteFlag && SA.notesWidget){SA.notesWidget.EventuallySaveUserNote();}
    }

    /*
    // The real problem is aliasing.  Line is jagged with high frequency sampling artifacts.
    // Pass in the spacing as a hint to get rid of aliasing.
    LassoWidget.prototype.Decimate = function(shape, spacing) {
        // Keep looping over the line removing points until the line does not change.
        var modified = true;
        var sanityCheck = 0;
        while (modified) {
            modified = false;
            var newPoints = [];
            newPoints.push(shape.Points[0]);
            // Window of four points.
            var i = 3;
            while (i < shape.Points.length) {
                // Debugging a hang.  I do not think it occurs in decimate, but it might.
                if (++sanityCheck > 100000) {
                    alert("Decimate is takeing too long.");
                    return;
                }
                var p0 = shape.Points[i];
                var p1 = shape.Points[i-1];
                var p2 = shape.Points[i-2];
                var p3 = shape.Points[i-3];
                // Compute the average of the center two.
                var cx = (p1[0] + p2[0]) * 0.5;
                var cy = (p1[1] + p2[1]) * 0.5;
                // Find the perendicular normal.
                var nx = (p0[1] - p3[1]);
                var ny = -(p0[0] - p3[0]);
                var mag = Math.sqrt(nx*nx + ny*ny);
                nx = nx / mag;
                ny = ny / mag;
                mag = Math.abs(nx*(cx-shape.Points[i-3][0]) + ny*(cy-shape.Points[i-3][1]));
                // Mag metric does not distinguish between line and a stroke that double backs on itself.
                // Make sure the two point being merged are between the outer points 0 and 3.
                var dir1 = (p0[0]-p1[0])*(p3[0]-p1[0]) + (p0[1]-p1[1])*(p3[1]-p1[1]);
                var dir2 = (p0[0]-p2[0])*(p3[0]-p2[0]) + (p0[1]-p2[1])*(p3[1]-p2[1]);
                if (mag < spacing && dir1 < 0.0 && dir2 < 0.0) {
                    // Replace the two points with their average.
                    newPoints.push([cx, cy]);
                    modified = true;
                    // Skip the next point the window will have one old merged point,
                    // but that is ok because it is just used as reference and not altered.
                    i += 2;
                } else {
                    //  No modification.  Just move the window one.
                    newPoints.push(shape.Points[i-2]);
                    ++i;
                }
            }
            // Copy the remaing point / 2 points
            i = i-2;
            while (i < shape.Points.length) {
                newPoints.push(shape.Points[i]);
                ++i;
            }
            shape.Points = newPoints;
        }

        shape.UpdateBuffers(this.Layer.AnnotationView);
    }
    */
    LassoWidget.prototype.CombineStroke = function() {
        // This algorithm was desinged to have the first point be the same as the last point.
        // To generalize polylineWidgets and lassoWidgets, I changed this and put a closed
        // flag (which implicitely draws the last segment) in polyline.
        // It is easier to temporarily add the extra point and them remove it, than change the algorithm.
        this.Loop.Points.push(this.Loop.Points[0]);

        // Find the first and last intersection points between stroke and loop.
        var intersection0;
        var intersection1;
        for (var i = 1; i < this.Stroke.Points.length; ++i) {
            var pt0 = this.Stroke.Points[i-1];
            var pt1 = this.Stroke.Points[i];
            var tmp = this.FindIntersection(pt0, pt1);
            if (tmp) {
                // I need to insert the intersection in the stroke so
                // one stroke segment does not intersect loop twice.
                this.Stroke.Points.splice(i,0,tmp.Point);
                if (intersection0 == undefined) {
                    intersection0 = tmp;
                    intersection0.StrokeIndex = i;
                } else {
                    // If a point was added before first intersection,
                    // its index needs to be updated too.
                    if (tmp.LoopIndex < intersection0.LoopIndex) {
                        intersection0.LoopIndex += 1;
                    }
                    intersection1 = tmp;
                    intersection1.StrokeIndex = i;
                }
            }
        }

        var sanityCheck = 0;

        // If we have two intersections, clip the loop with the stroke.
        if (intersection1 != undefined) {
            // We will have two parts.
            // Build both loops keeing track of their lengths.
            // Keep the longer part.
            var points0 = [];
            var len0 = 0.0;
            var points1 = [];
            var len1 = 0.0;
            var i;
            // Add the clipped stroke to both loops.
            for (i = intersection0.StrokeIndex; i < intersection1.StrokeIndex; ++i) {
                points0.push(this.Stroke.Points[i]);
                points1.push(this.Stroke.Points[i]);
            }
            // Now the two new loops take different directions around the original loop.
            // Decreasing
            i = intersection1.LoopIndex;
            while (i != intersection0.LoopIndex) {
                if (++sanityCheck > 1000000) {
                    alert("Combine loop 1 is taking too long.");
                    return;
                }
                points0.push(this.Loop.Points[i]);
                var dx = this.Loop.Points[i][0];
                var dy = this.Loop.Points[i][1];
                // decrement around loop.  First and last loop points are the same.
                if (--i == 0) { i = this.Loop.Points.length - 1;}
                // Integrate distance.
                dx -= this.Loop.Points[i][0];
                dy -= this.Loop.Points[i][1];
                len0 += Math.sqrt(dx*dx + dy*dy);
            }
            // Duplicate the first point in the loop
            points0.push(intersection0.Point);

            // Increasing
            i = intersection1.LoopIndex;
            while (i != intersection0.LoopIndex) {
                if (++sanityCheck > 1000000) {
                    alert("Combine loop 2 is taking too long.");
                    return;
                }
                points1.push(this.Loop.Points[i]);
                var dx = this.Loop.Points[i][0];
                var dy = this.Loop.Points[i][1];
                //increment around loop.  First and last loop points are the same.
                if (++i == this.Loop.Points.length - 1) { i = 0;}
                // Integrate distance.
                dx -= this.Loop.Points[i][0];
                dy -= this.Loop.Points[i][1];
                len1 += Math.sqrt(dx*dx + dy*dy);
            }
            // Duplicate the first point in the loop
            points1.push(intersection0.Point);

            if (len0 > len1) {
                this.Loop.Points = points0;
            } else {
                this.Loop.Points = points1;
            }

            if (window.SA) {SA.RecordState();}
        }

        // Remove the extra point added at the begining of this method.
        this.Loop.Points.pop();
        this.Loop.UpdateBuffers(this.Layer.AnnotationView);
        this.ComputeActiveCenter();

        this.Stroke = false;
        this.Layer.EventuallyDraw();
    }

    // tranform all points so p0 is origin and p1 maps to (1,0)
    // Returns false if no intersection,
    // If there is an intersection, it adds that point to the loop.
    // It returns {Point: newPt, LoopIndex: i} .
    LassoWidget.prototype.FindIntersection = function(p0, p1) {
        var best = false;
        var p = [(p1[0]-p0[0]), (p1[1]-p0[1])];
        var mag = Math.sqrt(p[0]*p[0] + p[1]*p[1]);
        if (mag < 0.0) { return false;}
        p[0] = p[0] / mag;
        p[1] = p[1] / mag;

        var m0 = this.Loop.Points[0];
        var n0 = [(m0[0]-p0[0])/mag, (m0[1]-p0[1])/mag];
        var k0 = [(n0[0]*p[0]+n0[1]*p[1]), (n0[1]*p[0]-n0[0]*p[1])];

        for (var i = 1; i < this.Loop.Points.length; ++i) {
            var m1 = this.Loop.Points[i];
            // Avoid an infinite loop inserting points.
            if (p0 == m0 || p0 == m1) { continue;}
            var n1 = [(m1[0]-p0[0])/mag, (m1[1]-p0[1])/mag];
            var k1 = [(n1[0]*p[0]+n1[1]*p[1]), (n1[1]*p[0]-n1[0]*p[1])];
            if ((k1[1] >= 0.0 && k0[1] <= 0.0) || (k1[1] <= 0.0 && k0[1] >= 0.0)) {
                var k = k0[1] / (k0[1]-k1[1]);
                var x = k0[0] + k*(k1[0]-k0[0]);
                if (x > 0 && x <=1) {
                    var newPt = [(m0[0]+k*(m1[0]-m0[0])), (m0[1]+k*(m1[1]-m0[1]))];
                    if ( ! best || x < best.k) {
                        best = {Point: newPt, LoopIndex: i, k: x};
                    }
                }
            }
            m0 = m1;
            n0 = n1;
            k0 = k1;
        }
        if (best) {
            this.Loop.Points.splice(best.LoopIndex,0,best.Point);
        }

        return best;
    }

    // This is not actually needed!  So it is not used.
    LassoWidget.prototype.IsPointInsideLoop = function(x, y) {
        // Sum up angles.  Inside poitns will sum to 2pi, outside will sum to 0.
        var angle = 0.0;
        var pt0 = this.Loop.Points[this.Loop.length - 1];
        for ( var i = 0; i < this.Loop.length; ++i)
        {
            var pt1 = this.Loop.Points[i];
            var v0 = [pt0[0]-x, pt0[1]-y];
            var v1 = [pt1[0]-x, pt1[1]-y];
            var mag0 = Math.sqrt(v0[0]*v0[0] + v0[1]*v0[1]);
            var mag1 = Math.sqrt(v1[0]*v1[0] + v1[1]*v1[1]);
            angle += Math.arcsin((v0[0]*v1[1] - v0[1]*v1[0])/(mag0*mag1));
        }

        return (angle > 3.14 || angle < -3.14);
    }

    LassoWidget.prototype.ComputeArea = function() {
        var area = 0.0;
        // Use the active center. It should be more numerical stable.
        // Iterate over triangles
        var vx1 = this.Loop.Points[0][0] - this.ActiveCenter[0];
        var vy1 = this.Loop.Points[0][1] - this.ActiveCenter[1];
        for (var j = 1; j < this.Loop.Points.length; ++j) {
            // Area of triangle is 1/2 magnitude of cross product.
            var vx2 = vx1;
            var vy2 = vy1;
            vx1 = this.Loop.Points[j][0] - this.ActiveCenter[0];
            vy1 = this.Loop.Points[j][1] - this.ActiveCenter[1];
            area += (vx1*vy2) - (vx2*vy1);
        }

        if (area < 0) {
            area = -area;
        }
        return area;
    }

    SAM.LassoWidget = LassoWidget;

})();


text:
package main

import (
	"fmt"
	"sort"
	"strings"

	"github.com/cloudfoundry/buildpacks-ci/tasks/cnb/helpers"
)

func GenerateCommitMessage(oldDeps, newDeps Dependencies, dep helpers.Dependency, buildpackTOMLOutputPath string, storyID int) string {
	added, rebuilt, stacks := findAddedDeps(dep, oldDeps, newDeps)

	removedDeps, stacks := findRemovedDeps(dep, oldDeps, newDeps, stacks)

	return formCommitMessage(dep, added, rebuilt, removedDeps, stacks, buildpackTOMLOutputPath, storyID)
}

func findAddedDeps(dep helpers.Dependency, oldDeps, newDeps Dependencies) (bool, bool, map[string]bool) {
	var added, rebuilt bool
	uniqueStacks := map[string]bool{}

	for _, newDep := range newDeps {
		if newDep.ID != dep.ID || newDep.Version != dep.Version {
			continue
		}

		oldDep, exists := oldDeps.findDependency(newDep)
		if exists && rebuild(oldDep, newDep) {
			rebuilt = true
		} else if !exists {
			added = true
		} else {
			continue
		}

		for _, stack := range newDep.Stacks {
			uniqueStacks[stack] = true
		}
	}

	return added, rebuilt, uniqueStacks
}

func findRemovedDeps(dep helpers.Dependency, oldDeps, newDeps Dependencies, stacks map[string]bool) (map[string]bool, map[string]bool) {
	removedDeps := map[string]bool{}

	for _, oldDep := range oldDeps {
		if oldDep.ID != dep.ID {
			continue
		}

		if !newDeps.containsDependency(oldDep) {
			removedDeps[oldDep.ID+" "+oldDep.Version] = true
			for _, stack := range oldDep.Stacks {
				stacks[stack] = true
			}
		}
	}

	return removedDeps, stacks
}

func formCommitMessage(dep helpers.Dependency, added, rebuilt bool, removedDeps, stacks map[string]bool, buildpackTOMLOutputPath string, storyID int) string {
	if noChanges(added, rebuilt, removedDeps) {
		return ""
	}

	var commitMessage string
	if added {
		commitMessage = fmt.Sprintf("Add %s %s", dep.ID, dep.Version)
	} else {
		commitMessage = fmt.Sprintf("Rebuild %s %s", dep.ID, dep.Version)
	}

	if len(removedDeps) > 0 {
		commitMessage += fmt.Sprintf(", remove %s", joinMap(removedDeps))
	}

	commitMessage += fmt.Sprintf(" in %s", buildpackTOMLOutputPath)
	commitMessage += fmt.Sprintf("\n\nfor stack(s) %s [#%d]", joinMap(stacks), storyID)

	return commitMessage
}

func noChanges(added, rebuilt bool, removedDeps map[string]bool) bool {
	return !added && !rebuilt && len(removedDeps) == 0
}

func rebuild(dep, newDep helpers.Dependency) bool {
	return dep.SHA256 != newDep.SHA256 || dep.URI != newDep.URI
}

func joinMap(m map[string]bool) string {
	var a []string
	for s := range m {
		a = append(a, s)
	}
	sort.Strings(a)
	return strings.Join(a, ", ")
}


text:
namespace cc {

// static
scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
  const bool is_offscreen = true;
  const bool share_resources = true;
  gpu::gles2::ContextCreationAttribHelper attribs;
  attribs.alpha_size = 8;
  attribs.blue_size = 8;
  attribs.green_size = 8;
  attribs.red_size = 8;
  attribs.depth_size = 24;
  attribs.stencil_size = 8;
  attribs.samples = 0;
  attribs.sample_buffers = 0;
  attribs.fail_if_major_perf_caveat = false;
  attribs.bind_generates_resource = false;
  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;

  scoped_ptr<gpu::GLInProcessContext> context =
      make_scoped_ptr(gpu::GLInProcessContext::Create(
          NULL,
          NULL,
          is_offscreen,
          gfx::kNullAcceleratedWidget,
          gfx::Size(1, 1),
          NULL,
          share_resources,
          attribs,
          gpu_preference,
          gpu::GLInProcessContextSharedMemoryLimits()));

  DCHECK(context);
  return context.Pass();
}

TestInProcessContextProvider::TestInProcessContextProvider()
    : context_(CreateTestInProcessContext()) {}

TestInProcessContextProvider::~TestInProcessContextProvider() {
}

bool TestInProcessContextProvider::BindToCurrentThread() { return true; }

gpu::gles2::GLES2Interface* TestInProcessContextProvider::ContextGL() {
  return context_->GetImplementation();
}

gpu::ContextSupport* TestInProcessContextProvider::ContextSupport() {
  return context_->GetImplementation();
}

namespace {

// Singleton used to initialize and terminate the gles2 library.
class GLES2Initializer {
 public:
  GLES2Initializer() { ::gles2::Initialize(); }

  ~GLES2Initializer() { ::gles2::Terminate(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
};

static base::LazyInstance<GLES2Initializer> g_gles2_initializer =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

static void BindGrContextCallback(const GrGLInterface* interface) {
  TestInProcessContextProvider* context_provider =
      reinterpret_cast<TestInProcessContextProvider*>(interface->fCallbackData);

  gles2::SetGLContext(context_provider->ContextGL());
}

class GrContext* TestInProcessContextProvider::GrContext() {
  if (gr_context_)
    return gr_context_.get();

  // The GrGLInterface factory will make GL calls using the C GLES2 interface.
  // Make sure the gles2 library is initialized first on exactly one thread.
  g_gles2_initializer.Get();
  gles2::SetGLContext(ContextGL());

  skia::RefPtr<GrGLInterface> interface =
      skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding());
  interface->fCallback = BindGrContextCallback;
  interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);

  gr_context_ = skia::AdoptRef(GrContext::Create(
      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));

  return gr_context_.get();
}

ContextProvider::Capabilities
TestInProcessContextProvider::ContextCapabilities() {
  return ContextProvider::Capabilities();
}

bool TestInProcessContextProvider::IsContextLost() { return false; }

void TestInProcessContextProvider::VerifyContexts() {}

void TestInProcessContextProvider::DeleteCachedResources() {
  if (gr_context_)
    gr_context_->freeGpuResources();
}

bool TestInProcessContextProvider::DestroyedOnMainThread() { return false; }

void TestInProcessContextProvider::SetLostContextCallback(
    const LostContextCallback& lost_context_callback) {}

void TestInProcessContextProvider::SetMemoryPolicyChangedCallback(
    const MemoryPolicyChangedCallback& memory_policy_changed_callback) {}

}  // namespace cc


text:
<!DOCTYPE html>

		<title>Drag-and-Drop between tables in DataTable</title>
		<link rel="stylesheet" href="../../../codebase/webix.css" type="text/css" charset="utf-8">

		<link rel="stylesheet" type="text/css" href="../common/samples.css">

Drag-and-Drop between tables


text:
package com.datastax.driver.osgi;

import com.datastax.driver.osgi.api.MailboxException;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.testng.listener.PaxExam;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import static com.datastax.driver.osgi.BundleOptions.*;
import static org.ops4j.pax.exam.CoreOptions.options;

@Listeners({CCMBridgeListener.class, PaxExam.class})
public class MailboxServiceGuava18IT extends MailboxServiceTests {

    @Configuration
    public Option[] guava18Config() {
        return options(
                defaultOptions(),
                nettyBundles(),
                guavaBundle().version("18.0"),
                driverBundle(),
                extrasBundle(),
                mappingBundle(),
                mailboxBundle()
        );
    }

    /**
     * Exercises a 'mailbox' service provided by an OSGi bundle that depends on the driver with
     * Guava 18 explicitly enforced.
     *
     * @test_category packaging
     * @expected_result Can create, retrieve and delete data using the mailbox service.
     * @jira_ticket JAVA-620
     * @since 2.0.10, 2.1.5
     */
    @Test(groups = "short")
    public void test_guava_18() throws MailboxException {
        checkService();
    }
}


text:
"use strict";
module.exports = require("@apidevtools/json-schema-ref-parser");


text:
/**
 * Auto-configuration for task execution and scheduling.
 */
package org.springframework.boot.autoconfigure.task;


text:
static const struct {
    SkBitmap::Config    fPrefConfig;
    bool                fDither;
} gRec[] = {
    { SkBitmap::kIndex8_Config,     false },
    { SkBitmap::kARGB_8888_Config,  false },
    { SkBitmap::kARGB_4444_Config,  false },
    { SkBitmap::kARGB_4444_Config,  true },
    { SkBitmap::kRGB_565_Config,    false },
    { SkBitmap::kRGB_565_Config,    true },
};

class DecodeView : public SkView {
public:
    SkBitmap fBitmap[SK_ARRAY_COUNT(gRec)];

	DecodeView() {
        SkFILEStream stream("/skimages/index.png");
        SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
        if (codec) {
            for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
                stream.rewind();
                codec->setDitherImage(gRec[i].fDither);
                codec->decode(&stream, &fBitmap[i], gRec[i].fPrefConfig,
                              SkImageDecoder::kDecodePixels_Mode);
            }
        }
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "ImageDecoder");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(0xFFDDDDDD);
//        canvas->drawColor(SK_ColorWHITE);
    }

    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);

        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        for (size_t i = 0; i < SK_ARRAY_COUNT(fBitmap); i++) {
            canvas->drawBitmap(fBitmap[i], 0, 0);
            canvas->translate(SkIntToScalar(fBitmap[i].width()), 0);
        }
    }
private:
    typedef SkView INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() { return new DecodeView; }
static SkViewRegister reg(MyFactory);


text:
package io.gravitee.repository.elasticsearch.spring;

import io.gravitee.repository.analytics.api.AnalyticsRepository;
import io.gravitee.repository.elasticsearch.analytics.ElasticAnalyticsRepository;
import io.gravitee.repository.elasticsearch.configuration.ElasticConfiguration;
import io.gravitee.repository.elasticsearch.healthcheck.ElasticHealthCheckRepository;
import io.gravitee.repository.elasticsearch.log.ElasticLogRepository;
import io.gravitee.repository.elasticsearch.monitoring.ElasticMonitoringRepository;
import io.gravitee.repository.healthcheck.api.HealthCheckRepository;
import io.gravitee.repository.log.api.LogRepository;
import io.gravitee.repository.monitoring.MonitoringRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author David BRASSELY (david.brassely at graviteesource.com)
 * @author GraviteeSource Team
 */
@Configuration
public class AnalyticsRepositoryConfiguration {

    @Bean
    public ElasticClientFactory elasticClientFactory() {
        return new ElasticClientFactory();
    }

    @Bean
    public ElasticConfiguration elasticConfiguration() {
        return new ElasticConfiguration();
    }

    @Bean
    public HealthCheckRepository healthCheckRepository() {
        return new ElasticHealthCheckRepository();
    }

    @Bean
    public AnalyticsRepository analyticsRepository() {
        return new ElasticAnalyticsRepository();
    }

    @Bean
    public LogRepository logRepository() {
        return new ElasticLogRepository();
    }

    @Bean
    public MonitoringRepository monitoringRepository() {
        return new ElasticMonitoringRepository();
    }
}


text:
<?php

// THEME OPTIONS /////////////////////////////////////////////

/*//**//**//**//*//**//**//**//*//**//**//**//*//**//**//**/
// Les options du thème accessibles via Wordpress.
// wp-admin/themes.php?page=theme_options
/*//**//**//**//*//**//**//**//*//**//**//**//*//**//**//**/

require_once('options/backoffice.php');
add_action('admin_init', 'themeoptions_backofficeRegister');
add_action('admin_menu', 'themeoptions_backofficeAdd_page');

add_action('admin_enqueue_scripts', 'themeoptions_backofficeEnqueue_scripts'); // Ajout des liens CSS et JS de la page d'administration.
add_action('wp_before_admin_bar_render', 'themeoptions_backofficeBar_render'); // Ajout d'un lien dans la barre d'administration de Wordpress.

add_filter('option_page_capability_bodyrock_options', 'themeoptions_backofficeCapability'); // Gestion des droits d'accès à la page.

if ( is_admin() ) : // Load only if we are viewing an admin page
	// Rendu de la page Options du thème dans l'administration de Wordpress.
	require 'options/view.php';
	// Validation des données à l'enregistrement des données.
	require 'options/validation.php';
endif;  // EndIf is_admin()

// GET /////////////////////////////////////////////
// Retourne les options actives
function br_themeoptionsGet($check_option=false) { // bodyrock_get_theme_options

	if($check_option!=false) {

		$options=get_option('brthemeoptions', themeoptionsGet_default());
		return (isset($options[$check_option]) ? $options[$check_option] : 'Option non existante.');

	}
	else return get_option('brthemeoptions', themeoptionsGet_default());

}

// GET DEFAULT /////////////////////////////////////////////
// Récupère les valeurs par défaut des options
function themeoptionsGet_default()
{
  $default = array(
    'iconset'  			=> 'glyphicon',
    'allbsjs'  			=> 1,
	'image_sizes' 		=> '',
	'fonts_google'		=> 'Doppio+One::latin,Roboto+Slab::latin,Open+Sans::latin,Ubuntu::latin',
	'googleanalyticsid'     => false
  );

  return apply_filters('brthemeoptions', $default);
}

?>


text:
package com.iappsam.entities.forms;

import static org.junit.Assert.*;

import org.junit.Test;

import com.iappsam.forms.IIRUP;

public class IIRUPTest {

	@Test
	public void sameIIRUP() {
		IIRUP iirup = new IIRUP();
		iirup.setId(1);

		IIRUP iirup2 = new IIRUP();
		iirup2.setId(1);

		assertEquals(iirup, iirup2);
	}
}


text:
<?php
/**
 * Created by PhpStorm.
 * User: bill
 * Date: 20.02.15
 * Time: 12:15
 */

namespace app\modules\directory\controllers;

use app\modules\directory\models\Employee;
use app\modules\directory\models\ImportForm;
use yii\helpers\Json;
use yii\web\Controller;
use yii\web\UploadedFile;

class EmployeeController extends Controller{

    public function actionAutoComplete($q = null) {
        $result = [];
        /** @var $item Employee */
        foreach(Employee::findByName($q, true)->all() as $item) {
            $result[] = ['value' => $item->fullName, 'post' => $item->post];
        }
        echo Json::encode($result);
    }

    public function actionImport()
    {
        $model = new ImportForm();

        if (\Yii::$app->request->isPost) {

            $model->datafile = UploadedFile::getInstance($model, 'datafile');
            $model->import();
        }

        return $this->render('import', ['model' => $model]);
    }
}


text:
import pytest

def test_en_tokenizer_handles_basic_contraction(en_tokenizer):
    text = "don't giggle"
    tokens = en_tokenizer(text)
    assert len(tokens) == 3
    assert tokens[1].text == "n't"
    text = "i said don't!"
    tokens = en_tokenizer(text)
    assert len(tokens) == 5
    assert tokens[4].text == "!"

@pytest.mark.parametrize("text", ["`ain't", """"isn't""", "can't!"])
def test_en_tokenizer_handles_basic_contraction_punct(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 3

@pytest.mark.parametrize(
    "text_poss,text", [("Robin's", "Robin"), ("Alexis's", "Alexis")]
)
def test_en_tokenizer_handles_poss_contraction(en_tokenizer, text_poss, text):
    tokens = en_tokenizer(text_poss)
    assert len(tokens) == 2
    assert tokens[0].text == text
    assert tokens[1].text == "'s"

@pytest.mark.parametrize("text", ["schools'", "Alexis'"])
def test_en_tokenizer_splits_trailing_apos(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 2
    assert tokens[0].text == text.split("'")[0]
    assert tokens[1].text == "'"

@pytest.mark.parametrize("text", ["'em", "nothin'", "ol'"])
def test_en_tokenizer_doesnt_split_apos_exc(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 1
    assert tokens[0].text == text

@pytest.mark.parametrize("text", ["we'll", "You'll", "there'll", "this'll", "those'll"])
def test_en_tokenizer_handles_ll_contraction(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 2
    assert tokens[0].text == text.split("'")[0]
    assert tokens[1].text == "'ll"

@pytest.mark.parametrize(
    "text_lower,text_title", [("can't", "Can't"), ("ain't", "Ain't")]
)
def test_en_tokenizer_handles_capitalization(en_tokenizer, text_lower, text_title):
    tokens_lower = en_tokenizer(text_lower)
    tokens_title = en_tokenizer(text_title)
    assert tokens_title[0].text == tokens_lower[0].text.title()
    assert tokens_lower[0].text == tokens_title[0].text.lower()
    assert tokens_lower[1].text == tokens_title[1].text

@pytest.mark.parametrize("pron", ["I", "You", "He", "She", "It", "We", "They"])
@pytest.mark.parametrize("contraction", ["'ll", "'d"])
def test_en_tokenizer_keeps_title_case(en_tokenizer, pron, contraction):
    tokens = en_tokenizer(pron + contraction)
    assert tokens[0].text == pron
    assert tokens[1].text == contraction

@pytest.mark.parametrize("exc", ["Ill", "ill", "Hell", "hell", "Well", "well"])
def test_en_tokenizer_excludes_ambiguous(en_tokenizer, exc):
    tokens = en_tokenizer(exc)
    assert len(tokens) == 1

@pytest.mark.parametrize(
    "wo_punct,w_punct", [("We've", "`We've"), ("couldn't", "couldn't)")]
)
def test_en_tokenizer_splits_defined_punct(en_tokenizer, wo_punct, w_punct):
    tokens = en_tokenizer(wo_punct)
    assert len(tokens) == 2
    tokens = en_tokenizer(w_punct)
    assert len(tokens) == 3

@pytest.mark.parametrize("text", ["e.g.", "p.m.", "Jan.", "Dec.", "Inc."])
def test_en_tokenizer_handles_abbr(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 1

def test_en_tokenizer_handles_exc_in_text(en_tokenizer):
    text = "It's mediocre i.e. bad."
    tokens = en_tokenizer(text)
    assert len(tokens) == 6
    assert tokens[3].text == "i.e."

@pytest.mark.parametrize("text", ["1am", "12a.m.", "11p.m.", "4pm"])
def test_en_tokenizer_handles_times(en_tokenizer, text):
    tokens = en_tokenizer(text)
    assert len(tokens) == 2

@pytest.mark.parametrize(
    "text,norms",
    [
        ("I'm", ["i", "am"]),
        ("shan't", ["shall", "not"]),
        (
            "Many factors cause cancer 'cause it is complex",
            ["many", "factors", "cause", "cancer", "because", "it", "is", "complex"],
        ),
    ],
)
def test_en_tokenizer_norm_exceptions(en_tokenizer, text, norms):
    tokens = en_tokenizer(text)
    assert [token.norm_ for token in tokens] == norms

@pytest.mark.parametrize("text,norm", [("Jan.", "January"), ("'cuz", "because")])
def test_en_lex_attrs_norm_exceptions(en_tokenizer, text, norm):
    tokens = en_tokenizer(text)
    assert tokens[0].norm_ == norm


text:
<?php namespace App\Http\Requests;

use App\Http\Requests\Request;

class StoreContactRequest extends Request {

	public function authorize()
	{
		return True;
	}

	public function rules()
	{
		return [
          'subject'=>['required','min:2'],
          'name' => ['required', 'min:3'],
          'email' => ['required'],

		];
	}

}