public ModelConfiguration(
            [NotNull] IModel model,
            [NotNull] CustomConfiguration customConfiguration,
            [NotNull] IRelationalAnnotationProvider extensionsProvider,
            [NotNull] CSharpUtilities cSharpUtilities,
            [NotNull] ModelUtilities modelUtilities)
        {
            Check.NotNull(model, nameof(model));
            Check.NotNull(customConfiguration, nameof(customConfiguration));
            Check.NotNull(extensionsProvider, nameof(extensionsProvider));
            Check.NotNull(cSharpUtilities, nameof(modelUtilities));
            Check.NotNull(modelUtilities, nameof(cSharpUtilities));

            Model = model;
            CustomConfiguration = customConfiguration;
            ExtensionsProvider  = extensionsProvider;
            CSharpUtilities     = cSharpUtilities;
            ModelUtilities      = modelUtilities;
        }
        public virtual Task<ReverseEngineerFiles> GenerateAsync(
            [NotNull] ReverseEngineeringConfiguration configuration,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(configuration, nameof(configuration));

            cancellationToken.ThrowIfCancellationRequested();

            configuration.CheckValidity();

            var metadataModel = GetMetadataModel(configuration);
            var @namespace = ConstructNamespace(configuration.ProjectRootNamespace,
                    configuration.ProjectPath, configuration.OutputPath);

            var customConfiguration = new CustomConfiguration()
            {
                ConnectionString = configuration.ConnectionString,
                ContextClassName = configuration.ContextClassName,
                Namespace = @namespace,
                UseFluentApiOnly = configuration.UseFluentApiOnly,
            };
            var modelConfiguration = _modelConfigurationFactory
                .CreateModelConfiguration(metadataModel, customConfiguration);

            var dbContextClassName =
                string.IsNullOrWhiteSpace(customConfiguration.ContextClassName)
                ? modelConfiguration.ClassName()
                : customConfiguration.ContextClassName;

            CheckOutputFiles(configuration.ProjectPath,
                configuration.OutputPath, dbContextClassName, metadataModel);

            var outputPath = configuration.OutputPath == null
                ? configuration.ProjectPath
                : (Path.IsPathRooted(configuration.OutputPath)
                    ? configuration.OutputPath
                    : Path.Combine(configuration.ProjectPath, configuration.OutputPath));

            return CodeWriter.WriteCodeAsync(
                modelConfiguration, outputPath, dbContextClassName, cancellationToken);
        }