public void Alter(ShapeDescriptor descriptor)
 {
     foreach (var configuration in _configurations)
     {
         configuration(descriptor);
     }
 }
        public ShapeTable GetShapeTable(string themeName)
        {
            return(_cacheManager.Get(themeName ?? "", true, x =>
            {
                Logger.Information("Start building shape table");

                var alterationSets = _parallelCacheContext.RunInParallel(_bindingStrategies, bindingStrategy =>
                {
                    Feature strategyDefaultFeature = bindingStrategy.Metadata.ContainsKey("Feature") ?
                                                     (Feature)bindingStrategy.Metadata["Feature"] :
                                                     null;

                    var builder = new ShapeTableBuilder(strategyDefaultFeature);
                    bindingStrategy.Value.Discover(builder);
                    return builder.BuildAlterations().ToReadOnlyCollection();
                });

                var alterations = alterationSets
                                  .SelectMany(shapeAlterations => shapeAlterations)
                                  .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
                                  .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority)
                                  .ToList();

                var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
                                  .Select(group => group.Aggregate(
                                              new ShapeDescriptor {
                    ShapeType = group.Key
                },
                                              (descriptor, alteration) =>
                {
                    alteration.Alter(descriptor);
                    return descriptor;
                })).ToList();

                foreach (var descriptor in descriptors)
                {
                    foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList())
                    {
                        var local = new ShapeDescriptor {
                            ShapeType = descriptor.ShapeType
                        };
                        alteration.Alter(local);
                        descriptor.BindingSources.Add(local.BindingSource);
                    }
                }

                var result = new ShapeTable
                {
                    Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
                    Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase),
                };

                _shapeTableEventHandlersWork.Value.Invoke(ctx => ctx.ShapeTableCreated(result), Logger);

                Logger.Information("Done building shape table");
                return result;
            }));
        }