public void AddParameter(String name, String description, String value)
 {
     using (Parameters.AcquireLock())
     {
         var parameter = new AttributeParameter <String>(name, description, value);
         parameter.PropertyChanged += ParameterPropertyChanged;
         Parameters.Add(parameter);
     }
 }
Ejemplo n.º 2
0
        private void SolveButton_Click(object sender, RoutedEventArgs e)
        {
            List <AttributeParameter> aps = new List <AttributeParameter>();
            AttributeParameter        ap  = GetAttributeParameterValue(AttributeParameter2.SelectionBoxItem.ToString());

            if (ap != null)
            {
                aps.Add(ap);
            }

            GenerateBarriers();

            RouteClosestFacilityParameters routeParams = new RouteClosestFacilityParameters()
            {
                Incidents        = IncidentsGraphicsLayer.Graphics,
                Barriers         = pointBarriers.Count > 0 ? pointBarriers : null,
                PolylineBarriers = polylineBarriers.Count > 0 ? polylineBarriers : null,
                PolygonBarriers  = polygonBarriers.Count > 0 ? polygonBarriers : null,
                Facilities       = facilitiesGraphicsLayer.Graphics,

                AttributeParameterValues = aps,
                ReturnDirections         = ReturnDirections2.IsChecked.HasValue ? ReturnDirections2.IsChecked.Value : false,
                DirectionsLanguage       = String.IsNullOrEmpty(DirectionsLanguage2.Text) ? new System.Globalization.CultureInfo("en-US") : new System.Globalization.CultureInfo(DirectionsLanguage2.Text),
                DirectionsLengthUnits    = GetDirectionsLengthUnits(DirectionsLengthUnits2.SelectionBoxItem.ToString().Trim()),
                DirectionsTimeAttribute  = DirectionsTimeAttributeName2.Text,

                ReturnRoutes           = ReturnRoutes2.IsChecked.HasValue ? ReturnRoutes2.IsChecked.Value : false,
                ReturnFacilities       = ReturnFacilities2.IsChecked.HasValue ? ReturnFacilities2.IsChecked.Value : false,
                ReturnIncidents        = ReturnIncidents2.IsChecked.HasValue ? ReturnIncidents2.IsChecked.Value : false,
                ReturnBarriers         = ReturnBarriers2.IsChecked.HasValue ? ReturnBarriers2.IsChecked.Value : false,
                ReturnPolylineBarriers = ReturnPolylineBarriers2.IsChecked.HasValue ? ReturnPolylineBarriers2.IsChecked.Value : false,

                ReturnPolygonBarriers      = ReturnPolygonBarriers2.IsChecked.HasValue ? ReturnPolygonBarriers2.IsChecked.Value : false,
                FacilityReturnType         = FacilityReturnType.ServerFacilityReturnAll,
                OutputLines                = GetOutputLines(OutputLines2.SelectionBoxItem.ToString().Trim()),
                DefaultCutoff              = string.IsNullOrEmpty(DefaultCutoff2.Text) ? 100 : double.Parse(DefaultCutoff2.Text),
                DefaultTargetFacilityCount = string.IsNullOrEmpty(DefaultTargetFacilityCount2.Text) ? 1 : int.Parse(DefaultTargetFacilityCount2.Text),

                TravelDirection       = GetFacilityTravelDirections(TravelDirection2.SelectionBoxItem.ToString()),
                OutSpatialReference   = string.IsNullOrEmpty(OutputSpatialReference2.Text) ? MyMap.SpatialReference : new SpatialReference(int.Parse(OutputSpatialReference2.Text)),
                AccumulateAttributes  = AccumulateAttributeNames2.Text.Split(','),
                ImpedanceAttribute    = ImpedanceAttributeName2.Text,
                RestrictionAttributes = RestrictionAttributeNames2.Text.Split(','),

                RestrictUTurns               = GetRestrictUTurns(RestrictUTurns2.SelectionBoxItem.ToString().Trim()),
                UseHierarchy                 = UseHierarchy2.IsChecked.HasValue ? UseHierarchy2.IsChecked.Value : false,
                OutputGeometryPrecision      = string.IsNullOrEmpty(OutputGeometryPrecision2.Text) ? 0 : double.Parse(OutputGeometryPrecision2.Text),
                OutputGeometryPrecisionUnits = GetGeometryPrecisionUnits(OutputGeometryPrecisionUnits2.SelectionBoxItem.ToString().Trim()),
            };

            if (myRouteTask.IsBusy)
            {
                myRouteTask.CancelAsync();
            }

            myRouteTask.SolveClosestFacilityAsync(routeParams);
        }
Ejemplo n.º 3
0
        private void SolveButton_Click(object sender, RoutedEventArgs e)
        {
            List <AttributeParameter> aps = new List <AttributeParameter>();
            AttributeParameter        ap  = GetAttributeParameterValue(AttributeParameterValues3.SelectionBoxItem.ToString());

            if (ap != null)
            {
                aps.Add(ap);
            }

            GenerateBarriers();

            RouteServiceAreaParameters routeParams = new RouteServiceAreaParameters()
            {
                Barriers         = pointBarriers.Count > 0 ? pointBarriers : null,
                PolylineBarriers = polylineBarriers.Count > 0 ? polylineBarriers : null,
                PolygonBarriers  = polygonBarriers.Count > 0 ? polygonBarriers : null,
                Facilities       = facilitiesGraphicsLayer.Graphics,
                //AttributeParameterValues = aps,

                DefaultBreaks = DefaultBreaks.Text,
                ExcludeSourcesFromPolygons = ExculdeSourcesFromPolygons.Text,
                MergeSimilarPolygonRanges  = MergeSimilarPolygonRanges.IsChecked.HasValue ? MergeSimilarPolygonRanges.IsChecked.Value : false,
                OutputLines     = GetOutputLines(OutputLines3.SelectionBoxItem.ToString()),
                OutputPolygons  = GetOutputPolygons(OutputPolygons.SelectionBoxItem.ToString()),
                OverlapLines    = OverlapLines3.IsChecked.HasValue ? OverlapLines3.IsChecked.Value : false,
                OverlapPolygons = OverlapPolygons3.IsChecked.HasValue ? OverlapPolygons3.IsChecked.Value : false,

                SplitLineAtBreaks        = SplitLinesAtBreaks.IsChecked.HasValue ? SplitLinesAtBreaks.IsChecked.Value : false,
                SplitPolygonsAtBreaks    = SplitPolygonsAtBreaks.IsChecked.HasValue ? SplitPolygonsAtBreaks.IsChecked.Value : false,
                TravelDirection          = GetFacilityTravelDirections(TravelDirections3.SelectionBoxItem.ToString()),
                TrimOuterPolygon         = TrimOuterPolygons.IsChecked.HasValue ? TrimOuterPolygons.IsChecked.Value : false,
                TrimPolygonDistance      = string.IsNullOrEmpty(TrimPolygonDistance.Text) ? 0 : double.Parse(TrimPolygonDistance.Text),
                TrimPolygonDistanceUnits = GetUnits(TrimPolygonDistanceUnits.SelectionBoxItem.ToString()),

                ReturnFacilities       = ReturnFacilities3.IsChecked.HasValue ? ReturnFacilities3.IsChecked.Value : false,
                ReturnBarriers         = ReturnBarriers3.IsChecked.HasValue ? ReturnBarriers3.IsChecked.Value : false,
                ReturnPolylineBarriers = ReturnPolylineBarriers3.IsChecked.HasValue ? ReturnPolylineBarriers3.IsChecked.Value : false,
                ReturnPolygonBarriers  = ReturnPolygonBarriers3.IsChecked.HasValue ? ReturnPolygonBarriers3.IsChecked.Value : false,
                OutSpatialReference    = string.IsNullOrEmpty(OutputSpatialReference3.Text) ? MyMap.SpatialReference : new SpatialReference(int.Parse(OutputSpatialReference3.Text)),

                AccumulateAttributes         = string.IsNullOrEmpty(AccumulateAttributeNames3.Text) ? null : AccumulateAttributeNames3.Text.Split(','),
                ImpedanceAttribute           = string.IsNullOrEmpty(ImpedanceAttributeName3.Text) ? string.Empty : ImpedanceAttributeName3.Text,
                RestrictionAttributes        = string.IsNullOrEmpty(RestrictionAttributeNames3.Text) ? null : RestrictionAttributeNames3.Text.Split(','),
                RestrictUTurns               = GetRestrictUTurns(RestrictUTurns3.SelectionBoxItem.ToString()),
                OutputGeometryPrecision      = string.IsNullOrEmpty(OutputGeometryPrecision3.Text) ? 0 : double.Parse(OutputGeometryPrecision3.Text),
                OutputGeometryPrecisionUnits = GetUnits(OutputGeometryPrecisionUnits3.SelectionBoxItem.ToString())
            };

            if (myRouteTask.IsBusy)
            {
                myRouteTask.CancelAsync();
            }

            myRouteTask.SolveServiceAreaAsync(routeParams);
        }
Ejemplo n.º 4
0
        private void AddParameter(AttributeParameter parameter, Boolean addToExistingSetParameters)
        {
            parameter.PropertyChanged += SetParameterPropertyChanged;

            if (addToExistingSetParameters)
            {
                using (ExistingSetParameters.AcquireLock())
                {
                    ExistingSetParameters.Add(parameter);
                }
            }
            else
            {
                using (NewSetParameters.AcquireLock())
                {
                    NewSetParameters.Add(parameter);
                }
            }
        }
Ejemplo n.º 5
0
        public void CheckLastAnd()
        {
            Argument argument = this[this.Count - 1];

            if (argument != null && argument.Parameter != null && argument.getExpression() is AndExpression)
            {
                AndExpression and = (AndExpression)argument.getExpression();
                if (and.Left is UnresolvedIdentifier)
                {
                    String id = ((UnresolvedIdentifier)and.Left).getName();
                    if (Char.IsLower(id[0]))
                    {
                        this.RemoveAt(this.Count - 1);
                        // add AttributeArgument
                        AttributeParameter parameter = new AttributeParameter(id);
                        Argument           attribute = new Argument(parameter, null);
                        this.Add(attribute);
                        // fix last argument
                        argument.Expression = and.Right;
                        this.Add(argument);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        public static async void Initialize(IServiceProvider serviceProvider)
        {
            Random       random     = new Random();
            const string loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam justo turpis, consequat a orci id, consequat fringilla libero. Curabitur sodales, neque sit amet dapibus dignissim, magna dolor iaculis tellus, et porta quam eros ac sem.";

            string[]  stringRemoves                      = new string[] { " ", ".", "," };
            const int userCount                          = 5;
            const int dictionaryCount                    = 6;
            const int dictionaryCountRandomRange         = 5;
            const int translationCount                   = 10;
            const int translationCountRandomRange        = 5;
            const int attributeCount                     = 5;
            const int attributeCountRandomRange          = 2;
            const int attributeValueCount                = 3;
            const int attributeValueCountRandomRange     = 2;
            const int attributeParameterCount            = 3;
            const int attributeParameterCountRandomRange = 1;
            const int viewerCount                        = 3;

            var users = new List <User>();

            using (var userManager = serviceProvider.GetRequiredService <UserManager <User> >())
            {
                if (!userManager.Users.Any())
                {
                    for (int i = 0; i < userCount; i++)
                    {
                        User user;
                        if (random.Next(3) == 2)
                        {
                            user = new User()
                            {
                                Email         = $"admin{i}@admin.xpl",
                                SecurityStamp = Guid.NewGuid().ToString(),
                                UserName      = $"Admin{i}"
                            };

                            await userManager.CreateAsync(user, "123456");

                            await userManager.AddToRoleAsync(user, "Administrator");
                        }
                        else
                        {
                            user = new User()
                            {
                                Email         = $"user{i}@user.xpl",
                                SecurityStamp = Guid.NewGuid().ToString(),
                                UserName      = $"User{i}"
                            };

                            await userManager.CreateAsync(user, "123456");

                            await userManager.AddToRoleAsync(user, "User");
                        }
                        users.Add(user);
                    }
                }
                else
                {
                    users = await userManager.Users.Include(u => u.Attributes).ToListAsync();
                }
            }

            using (var context = serviceProvider.GetRequiredService <MEMOContext>())
            {
                foreach (var user in users)
                {
                    var languages = await context.Languages.ToListAsync();

                    var attributes = new List <Entities.Attribute>();

                    if (!user.Attributes.Any())
                    {
                        for (int i = 0; i < attributeCount + (random.Next(2) == 0 ? random.Next(attributeCountRandomRange) : -random.Next(attributeCountRandomRange)); i++)
                        {
                            var           idx = random.Next(loremIpsum.Length - 6);
                            AttributeType type;
                            switch (random.Next(3))
                            {
                            case 0:
                                type = AttributeType.text; break;

                            case 1:
                                type = AttributeType.spinner; break;

                            case 2:
                                type = AttributeType.checkbox; break;

                            default:
                                type = AttributeType.text; break;
                            }

                            var attribute = new Entities.Attribute
                            {
                                Name = type == AttributeType.text ? "példamondat" : type == AttributeType.spinner ? "szófaj" : "fontos",
                                User = user,
                                Type = type
                            };
                            attributes.Add(attribute);
                            context.Add(attribute);
                        }
                    }
                    else
                    {
                        attributes = await context.Attributes.Where(a => a.UserId == user.Id)
                                     .Include(a => a.AttributeParameters)

                                     .ToListAsync();
                    }

                    foreach (var attribute in attributes)
                    {
                        if (attribute.Type == AttributeType.spinner)
                        {
                            if (!attribute.AttributeParameters.Any())
                            {
                                for (int i = 0; i < attributeParameterCount + (random.Next(2) == 0 ? random.Next(attributeParameterCountRandomRange) : -random.Next(attributeParameterCountRandomRange)); i++)
                                {
                                    var idx = random.Next(loremIpsum.Length - 6);
                                    var attributeParameter = new AttributeParameter
                                    {
                                        Value     = loremIpsum.CustomSubstring(idx, 6, stringRemoves),
                                        Attribute = attribute
                                    };
                                    context.Add(attributeParameter);
                                }
                            }
                        }
                    }

                    var dictionaries = new List <Dictionary>();

                    if (!context.UserDictionaries.Where(ud => ud.UserId == user.Id &&
                                                        ud.Type == UserType.owner)
                        .Any())
                    {
                        for (int i = 0; i < dictionaryCount + (random.Next(2) == 0 ? random.Next(dictionaryCountRandomRange) : -random.Next(dictionaryCountRandomRange)); i++)
                        {
                            var dictionary = new Dictionary
                            {
                                Name             = $"{i}_{user.UserName}_Dictionary",
                                Description      = loremIpsum.Substring(random.Next(loremIpsum.Length / 3)),
                                IsPublic         = random.Next(2) == 0,
                                IsFastAccessible = random.Next(3) != 2
                            };
                            dictionaries.Add(dictionary);
                            context.Add(dictionary);
                        }
                    }
                    else
                    {
                        dictionaries = await context.UserDictionaries.Include(ud => ud.Dictionary)
                                       .ThenInclude(d => d.Translations)
                                       .ThenInclude(t => t.AttributeValues)
                                       .Where(ud => ud.UserId == user.Id &&
                                              ud.Type == UserType.owner)
                                       .Select(ud => ud.Dictionary)

                                       .ToListAsync();
                    }

                    foreach (var dictionary in dictionaries)
                    {
                        var translations = new List <Translation>();

                        if (!dictionary.Translations.Any())
                        {
                            for (int i = 0; i < translationCount + (random.Next(2) == 0 ? random.Next(translationCountRandomRange) : -random.Next(translationCountRandomRange)); i++)
                            {
                                var idx1        = random.Next(loremIpsum.Length - 6);
                                var idx2        = random.Next(loremIpsum.Length - 6);
                                var translation = new Translation
                                {
                                    Original   = loremIpsum.CustomSubstring(idx1, 6, stringRemoves),
                                    Translated = loremIpsum.CustomSubstring(idx2, 6, stringRemoves),
                                    Color      = -13615201,
                                    Dictionary = dictionary
                                };
                                translations.Add(translation);
                                context.Add(translation);
                            }
                        }
                        else
                        {
                            translations = dictionary.Translations.ToList();
                        }

                        foreach (var traslation in translations)
                        {
                            if (!traslation.AttributeValues.Any())
                            {
                                for (int i = 0; i < attributeValueCount + (random.Next(2) == 0 ? random.Next(attributeValueCountRandomRange) : -random.Next(attributeValueCountRandomRange)); i++)
                                {
                                    var attribute      = attributes.ElementAt(random.Next(attributes.Count));
                                    var idx            = random.Next(loremIpsum.Length - 6);
                                    var attributeValue = new AttributeValue();

                                    if (attribute.Type == AttributeType.spinner && attribute.AttributeParameters.Any())
                                    {
                                        var attributeParameters = attribute.AttributeParameters;
                                        attributeValue = new AttributeValue
                                        {
                                            Value       = attributeParameters.ElementAt(random.Next(attributeParameters.Count)).Value,
                                            Translation = traslation,
                                            Attribute   = attribute
                                        };
                                    }
                                    else
                                    {
                                        attributeValue = new AttributeValue
                                        {
                                            Value       = attribute.Type == AttributeType.text ? loremIpsum.CustomSubstring(idx, 6, stringRemoves) : random.Next(2) == 0 ? "true" : "false",
                                            Translation = traslation,
                                            Attribute   = attribute
                                        };
                                    }

                                    context.Add(attributeValue);
                                }
                            }
                        }

                        if (!context.DictionaryLanguages.Where(dl => dl.DictionaryId == dictionary.Id).Any())
                        {
                            int firstLanguage = random.Next(languages.Count);

                            context.Add(new DictionaryLanguage
                            {
                                Type       = LanguageType.source,
                                Dictionary = dictionary,
                                Language   = languages.ElementAt(firstLanguage)
                            });

                            int secondLanguage;
                            do
                            {
                                secondLanguage = random.Next(languages.Count);
                            }while (firstLanguage == secondLanguage);

                            context.Add(new DictionaryLanguage
                            {
                                Type       = LanguageType.destination,
                                Dictionary = dictionary,
                                Language   = languages.ElementAt(secondLanguage)
                            });
                        }

                        if (!context.UserDictionaries.Where(ud => ud.Type == UserType.owner &&
                                                            ud.UserId == user.Id &&
                                                            ud.DictionaryId == dictionary.Id)
                            .Any())
                        {
                            context.Add(new UserDictionary
                            {
                                Type       = UserType.owner,
                                Dictionary = dictionary,
                                User       = user
                            });
                        }
                    }

                    await context.SaveChangesAsync();
                }

                foreach (var user in await context.Users.Include(u => u.UserDictionaries).ToListAsync())
                {
                    if (!user.UserDictionaries.Any(ud => ud.Type == UserType.viewer))
                    {
                        var publicDictionaries = await context.UserDictionaries
                                                 .Include(ud => ud.Dictionary)
                                                 .Where(ud => !ud.Dictionary
                                                        .UserDictionaries
                                                        .Any(ud => ud.UserId == user.Id &&
                                                             ud.Type == UserType.owner) &&
                                                        ud.Dictionary.IsPublic)
                                                 .Select(ud => ud.Dictionary)

                                                 .ToListAsync();

                        if (publicDictionaries.Count >= viewerCount)
                        {
                            for (int i = 0; i < viewerCount; i++)
                            {
                                var publicDictionary = publicDictionaries.ElementAt(random.Next(publicDictionaries.Count));
                                context.Add(new UserDictionary
                                {
                                    Type       = UserType.viewer,
                                    Dictionary = publicDictionary,
                                    User       = user
                                });
                                publicDictionaries.Remove(publicDictionary);
                            }
                        }
                    }
                }

                await context.SaveChangesAsync();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Uses the given parameters to add CodeDom arguments to the given attribute.
        /// Returns true if the arguments could be defined, or false if the values could
        /// not be converted to the required type. An error is also logged for failures.
        /// </summary>
        private bool AddArguments(
            CodeAttributeDeclaration attribute,
            Lazy <Type> attributeType,
            IReadOnlyList <AttributeParameter> parameters,
            bool isPositional
            )
        {
            Type[] constructorParameterTypes = null;

            for (int i = 0; i < parameters.Count; i++)
            {
                AttributeParameter parameter = parameters[i];
                CodeExpression     value;

                switch (parameter.Type.Kind)
                {
                case ParameterTypeKind.Literal:
                    // The exact value provided by the metadata is what we use.
                    // Note that this value is used verbatim, so its the user's
                    // responsibility to ensure that it is in the correct language.
                    value = new CodeSnippetExpression(parameter.Value);
                    break;

                case ParameterTypeKind.Typed:
                    if (string.Equals(parameter.Type.TypeName, "System.Type"))
                    {
                        // Types are a special case, because we can't convert a string to a
                        // type, but because we're using the CodeDom, we don't need to
                        // convert it. we can just create a type expression.
                        value = new CodeTypeOfExpression(parameter.Value);
                    }
                    else
                    {
                        // We've been told what type this parameter needs to be.
                        // If we cannot convert the value to that type, then we need to fail.
                        if (!TryConvertParameterValue(parameter.Type.TypeName, parameter.Value, out value))
                        {
                            return(false);
                        }
                    }

                    break;

                default:
                    if (isPositional)
                    {
                        // For positional parameters, infer the type
                        // using the constructor argument types.
                        if (constructorParameterTypes is null)
                        {
                            constructorParameterTypes = FindPositionalParameterTypes(attributeType.Value, parameters);
                        }

                        value = ConvertParameterValueToInferredType(
                            constructorParameterTypes[i],
                            parameter.Value,
                            $"#{i + 1}"     /* back to 1 based */
                            );
                    }
                    else
                    {
                        // For named parameters, use the type of the property if we can find it.
                        value = ConvertParameterValueToInferredType(
                            attributeType.Value?.GetProperty(parameter.Name)?.PropertyType,
                            parameter.Value,
                            parameter.Name
                            );
                    }

                    break;
                }

                attribute.Arguments.Add(new CodeAttributeArgument(parameter.Name, value));
            }

            return(true);
        }
Ejemplo n.º 8
0
        private string GenerateCode(out string extension)
        {
            extension = null;
            bool haveGeneratedContent = false;

            CodeDomProvider provider;

            try
            {
                provider = CodeDomProvider.CreateProvider(Language);
            }
            catch (SystemException e) when
#if FEATURE_SYSTEM_CONFIGURATION
                (e is ConfigurationException || e is SecurityException)
#else
            (e.GetType().Name == "ConfigurationErrorsException") //TODO: catch specific exception type once it is public https://github.com/dotnet/corefx/issues/40456
#endif
            {
                Log.LogErrorWithCodeFromResources("WriteCodeFragment.CouldNotCreateProvider", Language, e.Message);
                return(null);
            }

            extension = provider.FileExtension;

            var unit = new CodeCompileUnit();

            var globalNamespace = new CodeNamespace();
            unit.Namespaces.Add(globalNamespace);

            // Declare authorship. Unfortunately CodeDOM puts this comment after the attributes.
            string comment = ResourceUtilities.GetResourceString("WriteCodeFragment.Comment");
            globalNamespace.Comments.Add(new CodeCommentStatement(comment));

            if (AssemblyAttributes == null)
            {
                return(String.Empty);
            }

            // For convenience, bring in the namespaces, where many assembly attributes lie
            foreach (string name in NamespaceImports)
            {
                globalNamespace.Imports.Add(new CodeNamespaceImport(name));
            }

            foreach (ITaskItem attributeItem in AssemblyAttributes)
            {
                // Some attributes only allow positional constructor arguments, or the user may just prefer them.
                // To set those, use metadata names like "_Parameter1", "_Parameter2" etc.
                // If a parameter index is skipped, it's an error.
                IDictionary customMetadata = attributeItem.CloneCustomMetadata();

                // Some metadata may indicate the types of parameters. Use that metadata to determine
                // the parameter types. Those metadata items will be removed from the dictionary.
                IReadOnlyDictionary <string, ParameterType> parameterTypes = ExtractParameterTypes(customMetadata);

                var orderedParameters = new List <AttributeParameter?>(new AttributeParameter?[customMetadata.Count + 1] /* max possible slots needed */);
                var namedParameters   = new List <AttributeParameter>();

                foreach (DictionaryEntry entry in customMetadata)
                {
                    string name  = (string)entry.Key;
                    string value = (string)entry.Value;

                    // Get the declared type information for this parameter.
                    // If a type is not declared, then we infer the type.
                    if (!parameterTypes.TryGetValue(name, out ParameterType type))
                    {
                        type = new ParameterType {
                            Kind = ParameterTypeKind.Inferred
                        };
                    }

                    if (name.StartsWith("_Parameter", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!Int32.TryParse(name.Substring("_Parameter".Length), out int index))
                        {
                            Log.LogErrorWithCodeFromResources("General.InvalidValue", name, "WriteCodeFragment");
                            return(null);
                        }

                        if (index > orderedParameters.Count || index < 1)
                        {
                            Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", index);
                            return(null);
                        }

                        // "_Parameter01" and "_Parameter1" would overwrite each other
                        orderedParameters[index - 1] = new AttributeParameter {
                            Type = type, Value = value
                        };
                    }
                    else
                    {
                        namedParameters.Add(new AttributeParameter {
                            Name = name, Type = type, Value = value
                        });
                    }
                }

                bool encounteredNull = false;
                List <AttributeParameter> providedOrderedParameters = new();
                for (int i = 0; i < orderedParameters.Count; i++)
                {
                    if (!orderedParameters[i].HasValue)
                    {
                        // All subsequent args should be null, else a slot was missed
                        encounteredNull = true;
                        continue;
                    }

                    if (encounteredNull)
                    {
                        Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", i + 1 /* back to 1 based */);
                        return(null);
                    }

                    providedOrderedParameters.Add(orderedParameters[i].Value);
                }

                var attribute = new CodeAttributeDeclaration(new CodeTypeReference(attributeItem.ItemSpec));

                // We might need the type of the attribute if we need to infer the
                // types of the parameters. Search for it by the given type name,
                // as well as within the namespaces that we automatically import.
                Lazy <Type> attributeType = new(
                    () => Type.GetType(attribute.Name, throwOnError: false) ?? NamespaceImports.Select(x => Type.GetType($"{x}.{attribute.Name}", throwOnError: false)).FirstOrDefault(),
                    System.Threading.LazyThreadSafetyMode.None
                    );

                if (
                    !AddArguments(attribute, attributeType, providedOrderedParameters, isPositional: true) ||
                    !AddArguments(attribute, attributeType, namedParameters, isPositional: false))
                {
                    return(null);
                }

                unit.AssemblyCustomAttributes.Add(attribute);
                haveGeneratedContent = true;
            }

            var generatedCode = new StringBuilder();
            using (var writer = new StringWriter(generatedCode, CultureInfo.CurrentCulture))
            {
                provider.GenerateCodeFromCompileUnit(unit, writer, new CodeGeneratorOptions());
            }

            string code = generatedCode.ToString();

            // If we just generated infrastructure, don't bother returning anything
            // as there's no point writing the file
            return(haveGeneratedContent ? code : String.Empty);
        }