code: package it.unibz.inf.ontop.substitution;
  
  import com.google.common.collect.ImmutableList;
  import com.google.common.collect.ImmutableMap;
  import com.google.common.collect.ImmutableSet;
  import it.unibz.inf.ontop.model.term.ImmutableTerm;
  import it.unibz.inf.ontop.model.term.Variable;
  import it.unibz.inf.ontop.utils.VariableGenerator;
  
  import java.util.function.Function;
  import java.util.stream.Stream;
  
  /**
   * Accessible through Guice (recommended) or through CoreSingletons.
   */
  public interface SubstitutionFactory {
  
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution(ImmutableMap<Variable, T> newSubstitutionMap);
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution(Variable k1, T v1);
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution(Variable k1, T v1, Variable k2, T v2);
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution(Variable k1, T v1, Variable k2, T v2,
                                                                         Variable k3, T v3);
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution();
  
      <T extends ImmutableTerm> ImmutableSubstitution<T> getSubstitution(ImmutableList<Variable> variables, ImmutableList<T> values);
  
     ImmutableSubstitution<ImmutableTerm> getNullSubstitution(Stream<Variable> variables);
  
      Var2VarSubstitution getVar2VarSubstitution(ImmutableMap<Variable, Variable> substitutionMap);
  
      InjectiveVar2VarSubstitution getInjectiveVar2VarSubstitution(ImmutableMap<Variable, Variable> substitutionMap);
  
      InjectiveVar2VarSubstitution getInjectiveVar2VarSubstitution(Stream<Variable> stream, Function<Variable, Variable> transformer);
  
      InjectiveVar2VarSubstitution generateNotConflictingRenaming(VariableGenerator variableGenerator,
                                                                  ImmutableSet<Variable> variables);
  }
  