code: package it.unibz.inf.ontop.injection.impl;
  
  
  import com.google.common.collect.ImmutableList;
  import com.google.inject.Module;
  import it.unibz.inf.ontop.datalog.UnionFlattener;
  import it.unibz.inf.ontop.injection.OntopOptimizationConfiguration;
  import it.unibz.inf.ontop.injection.OntopOptimizationSettings;
  import it.unibz.inf.ontop.injection.OptimizationSingletons;
  import it.unibz.inf.ontop.injection.OptimizerFactory;
  import it.unibz.inf.ontop.iq.optimizer.*;
  import it.unibz.inf.ontop.iq.planner.QueryPlanner;
  import it.unibz.inf.ontop.iq.tools.UnionBasedQueryMerger;
  import it.unibz.inf.ontop.iq.transformer.*;
  import it.unibz.inf.ontop.iq.lens.LensUnfolder;
  import it.unibz.inf.ontop.iq.visitor.RequiredExtensionalDataNodeExtractor;
  
  public class OntopOptimizationModule extends OntopAbstractModule {
  
      private OntopOptimizationConfiguration configuration;
  
      protected OntopOptimizationModule(OntopOptimizationConfiguration configuration) {
          super(configuration.getSettings());
          // Temporary (will be dropped)
          this.configuration = configuration;
      }
  
  
      @Override
      protected void configure() {
          bind(OntopOptimizationSettings.class).toInstance(configuration.getSettings());
  
          // Executors
          bindFromSettings(UnionBasedQueryMerger.class);
          bindFromSettings(JoinLikeOptimizer.class);
          bindFromSettings(UnionAndBindingLiftOptimizer.class);
          bindFromSettings(UnionFlattener.class);
          bindFromSettings(TermTypeTermLifter.class);
          bindFromSettings(OrderBySimplifier.class);
          bindFromSettings(AggregationSimplifier.class);
          bindFromSettings(PostProcessableFunctionLifter.class);
          bindFromSettings(InnerJoinIQOptimizer.class);
          bindFromSettings(LeftJoinIQOptimizer.class);
          bindFromSettings(BooleanExpressionPushDownTransformer.class);
          bindFromSettings(EmptyRowsValuesNodeTransformer.class);
          bindFromSettings(GeneralStructuralAndSemanticIQOptimizer.class);
          bindFromSettings(QueryPlanner.class);
          bindFromSettings(SelfJoinSameTermIQOptimizer.class);
          bindFromSettings(RequiredExtensionalDataNodeExtractor.class);
          bindFromSettings(SelfJoinUCIQOptimizer.class);
          bindFromSettings(RedundantJoinFKOptimizer.class);
          bindFromSettings(BelowDistinctJoinWithClassUnionOptimizer.class);
          bindFromSettings(LensUnfolder.class);
          bindFromSettings(AggregationSplitter.class);
          bindFromSettings(FlattenLifter.class);
          bindFromSettings(FilterLifter.class);
          bindFromSettings(BooleanExpressionPushDownOptimizer.class);
  
          bind(OptimizationSingletons.class).to(OptimizationSingletonsImpl.class);
  
          Module optimizerModule = buildFactory(ImmutableList.of(
                  ExplicitEqualityTransformer.class,
                  TermTypeTermLiftTransformer.class,
                  DefinitionPushDownTransformer.class),
                  OptimizerFactory.class);
          install(optimizerModule);
          // Releases the configuration (enables some GC)
          this.configuration = null;
      }
  }
  