/**
  * @param lemma1
  * @param pos1
  * @param lemma2
  * @param pos2
  * @param relation
  * @param synset1
  * @param synset2
  * @param isNotCrossed
  * @param synset2No
  * @return
  * @throws LexicalResourceException
  */
 private LexicalRule<WordnetRuleInfo> newDirectedRule(
     String lemma1,
     PartOfSpeech pos1,
     String lemma2,
     PartOfSpeech pos2,
     WordNetRelation relation,
     Synset synset1,
     Synset synset2,
     int synset2No,
     boolean isNotCrossed)
     throws LexicalResourceException {
   int synset1No = getSynsetNo(lemma1, pos1, synset1);
   return isNotCrossed
       ? new LexicalRule<WordnetRuleInfo>(
           lemma1,
           pos1,
           lemma2,
           pos2,
           relation.toString(),
           RESOURCE_NAME,
           new WordnetRuleInfo(synset1, synset1No, synset2, synset2No, relation))
       : new LexicalRule<WordnetRuleInfo>(
           lemma2,
           pos2,
           lemma1,
           pos1,
           relation.toString(),
           RESOURCE_NAME,
           new WordnetRuleInfo(synset2, synset2No, synset1, synset1No, relation));
 }
  /**
   * Return all the rules matching the given lemma+pos of both sides of the rule, filtered to the
   * given relations and info. The rules are between 1 and #chainingLength WN edges long.
   *
   * @param lLemma
   * @param lPos
   * @param rLemma
   * @param rPos
   * @param relations
   * @param info
   * @param chainingLength
   * @return
   * @throws LexicalResourceException
   */
  List<LexicalRule<? extends WordnetRuleInfo>> getRules(
      String lLemma,
      PartOfSpeech lPos,
      String rLemma,
      PartOfSpeech rPos,
      Set<WordNetRelation> relations,
      WordnetRuleInfo info,
      int chainingLength)
      throws LexicalResourceException {
    // sanity
    checkRelationsBeforeUse(relations);
    checkInfo(info);
    if (lLemma == null) throw new LexicalResourceException("got null lLemma");
    if (rLemma == null) throw new LexicalResourceException("got null rLemma");

    List<LexicalRule<? extends WordnetRuleInfo>> rules =
        new Vector<LexicalRule<? extends WordnetRuleInfo>>();
    // carefully pull the two synsets
    List<Synset> lSelectSynsets = pullSynsets(lLemma, lPos, info.getLeftSenseNo());
    List<Synset> rSelectSynsets = pullSynsets(rLemma, rPos, info.getRightSenseNo());

    try {
      for (int lSynsetNo = 1; lSynsetNo <= lSelectSynsets.size(); lSynsetNo++) {
        Synset lSynset = lSelectSynsets.get(lSynsetNo - 1);

        for (int rSynsetNo = 1; rSynsetNo <= rSelectSynsets.size(); rSynsetNo++) {
          Synset rSynset = rSelectSynsets.get(rSynsetNo - 1);

          for (WordNetRelation relation : relations) {
            Set<Synset> neighbors =
                getSemanticOrLexicalNeighbors(lLemma, lSynset, relation, chainingLength);
            if (neighbors.contains(rSynset)
                || // usually, the relation connects between neighboring synsets
                doubleCheckContains(neighbors, rSynset)
                || (relation.equals(SYNONYM)
                    && lSynset.equals(
                        rSynset))) // special condition for SYNONYMs, which are just words within a
                                   // Synset
            {
              // just in case the given rPos or lPos are null, replace them with the POSs from the
              // synsets
              PartOfSpeech concreteLPos = lSynset.getPartOfSpeech().toPartOfSpeech();
              PartOfSpeech concreteRPos = rSynset.getPartOfSpeech().toPartOfSpeech();
              rules.add(
                  new LexicalRule<WordnetRuleInfo>(
                      lLemma,
                      concreteLPos,
                      rLemma,
                      concreteRPos,
                      relation.toString(),
                      RESOURCE_NAME,
                      new WordnetRuleInfo(lSynset, lSynsetNo, rSynset, rSynsetNo, relation)));
            }
          }
        }
      }
    } catch (WordNetException e) {
      throw new LexicalResourceException(
          "An error occured while loading the neighbors of a synset of <"
              + lLemma
              + ", "
              + lPos
              + "> :",
          e);
    }

    return rules;
  }