/**
   * Returns a new {@code ITranslationRuleGen}.
   *
   * @param systemMappingsDoc
   * @param userRelationsDoc
   * @param builtInSchemasDoc
   * @param system
   * @return a new {@code ITranslationGen}
   * @throws XMLParseException
   * @throws ConfigurationException for an illegal combination of options
   */
  public static ITranslationRuleGen newInstance(
      Document systemMappingsDoc,
      Document userRelationsDoc,
      Document builtInSchemasDoc,
      OrchestraSystem system)
      throws XMLParseException {
    boolean outerUnion = Config.getOuterUnion();
    boolean outerJoin = Config.getOuterJoin();
    List<Mapping> systemMappings =
        deserializeVerboseMappings(systemMappingsDoc.getDocumentElement(), system);
    List<RelationContext> userRelations =
        deserializeRelationContexts(userRelationsDoc.getDocumentElement(), system);
    Map<String, Schema> builtInSchemas =
        OrchestraSystem.deserializeBuiltInFunctions(builtInSchemasDoc);
    boolean isBidirectional = system.isBidirectional();

    checkOptions(isBidirectional, outerUnion, outerJoin);
    if (outerUnion) {
      return new OuterUnionTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    } else if (outerJoin) {
      return new OuterJoinTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    } else {
      return new DefaultTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    }
  }
  /**
   * Returns a new {@code ITranslationRuleGen}.
   *
   * @param systemMappings
   * @param userRelations
   * @param builtInSchemas
   * @param isBidirectional
   * @param bidirectional
   * @return a new {@code ITranslationGen}
   * @throws ConfigurationException for an illegal combination of options
   */
  public static ITranslationRuleGen newInstance(
      List<Mapping> systemMappings,
      List<RelationContext> userRelations,
      Map<String, Schema> builtInSchemas,
      boolean isBidirectional) {
    boolean outerUnion = Config.getOuterUnion();
    boolean outerJoin = Config.getOuterJoin();

    checkOptions(isBidirectional, outerUnion, outerJoin);
    if (outerUnion) {
      return new OuterUnionTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    } else if (outerJoin) {
      return new OuterJoinTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    } else {
      return new DefaultTranslationRuleGen(
          systemMappings, userRelations, builtInSchemas, isBidirectional);
    }
  }