@SuppressWarnings({"unchecked", "rawtypes"})
   ClauseMetaData(KnowledgeBase kb, int clauseIndex, ClauseModel clauseModel, boolean isTailRecursive) {
      this.clauseIndex = clauseIndex;
      this.term = clauseModel.getOriginal();
      this.consequent = clauseModel.getConsequent();
      Term antecedant = clauseModel.getAntecedant();
      this.conjunctions = toArrayOfConjunctions(antecedant);
      this.predicateFactories = new PredicateFactory[conjunctions.length];
      this.variablesInConjunction = new Set[conjunctions.length];
      this.isConjunctionMulipleResult = new boolean[conjunctions.length];
      boolean isSingleResult = true;
      boolean containsCut = false;
      int indexOfFirstMulipleResultConjuction = 0;
      int indexOfLastMulipleResultConjuction = 0;
      int numberOfMulipleResultConjuctions = 0;
      String consequentName = consequent.getName();
      for (int i = 0; i < conjunctions.length; i++) {
         Term c = conjunctions[i];
         variablesInConjunction[i] = TermUtils.getAllVariablesInTerm(c);
         boolean isRetryable;
         if (consequentName.equals(c.getName()) && c.getNumberOfArguments() == consequent.getNumberOfArguments()) {
            if (isTailRecursive && i == conjunctions.length - 1) {
               isRetryable = false;
            } else {
               isRetryable = true;
            }
         } else {
            predicateFactories[i] = getPredicateFactory(kb, c);
            if (predicateFactories[i] == null) {
               throw new RuntimeException();
            } else if (predicateFactories[i].getClass() == Cut.class) {
               containsCut = true;
               isRetryable = false;
            } else {
               isRetryable = isRetryable(predicateFactories[i], c.getArgs());
            }
         }
         if (isRetryable) {
            if (isSingleResult) {
               indexOfFirstMulipleResultConjuction = i;
               isSingleResult = false;
            }
            indexOfLastMulipleResultConjuction = i;
            numberOfMulipleResultConjuctions++;
            isConjunctionMulipleResult[i] = true;
         }
      }
      this.isSingleResult = isSingleResult;
      this.containsCut = containsCut;
      this.indexOfFirstMulipleResultConjuction = indexOfFirstMulipleResultConjuction;
      this.indexOfLastMulipleResultConjuction = indexOfLastMulipleResultConjuction;
      this.numberOfMulipleResultConjuctions = numberOfMulipleResultConjuctions;

      this.ignorableVariables = getConsequentVariablesThatCanBeIgnored();
   }