/**
   * Create code from this definition
   *
   * @param defCode code definition
   * @return code object
   */
  private ProcCode createCode(Code defCode) {
    if (!defCode.hasPatterns()) {
      throw new IllegalStateException("Field pattern can't be null.");
    }

    if (defCode.getTemplate() == null) {
      throw new IllegalStateException("Field template can't be null.");
    }

    ProcCode code = codes.get(defCode);
    if (code == null) {
      List<Pattern> confPatterns = defCode.getPatterns();
      List<ProcPattern> procPatterns = new ArrayList<ProcPattern>(confPatterns.size());

      for (Pattern confPattern : confPatterns) {
        procPatterns.add(createPattern(confPattern));
      }

      code =
          new ProcCode(
              procPatterns,
              createTemplate(defCode.getTemplate()),
              defCode.getName(),
              defCode.getPriority(),
              defCode.isTransparent());
      codes.put(defCode, code);
    }
    return code;
  }
 /**
  * Create a constant element for text parsing
  *
  * @param constant constant definition
  * @return pattern element for constant
  */
 private PatternConstant createPatternConstant(Constant constant) {
   if (!constants.containsKey(constant)) {
     constants.put(
         constant,
         new PatternConstant(constant.getValue(), constant.isIgnoreCase(), constant.isGhost()));
   }
   return constants.get(constant);
 }
 /**
  * Find or create the scope.
  *
  * @param scope the scope configuration
  * @return scope scope
  */
 private ProcScope createScope(Scope scope) {
   ProcScope created = createdScopes.get(scope);
   if (created == null) {
     created = new ProcScope(scope.getName());
     createdScopes.put(scope, created);
     created.setStrong(scope.isStrong());
     created.setIgnoreText(scope.isIgnoreText());
     if (scope.getParent() != null) {
       created.setParent(createScope(scope.getParent()));
     }
     Set<ProcCode> scopeCodes = new HashSet<ProcCode>();
     for (Code code : scope.getCodes()) {
       scopeCodes.add(createCode(code));
     }
     created.setScopeCodes(scopeCodes);
     created.setMin(scope.getMin());
     created.setMax(scope.getMax());
   }
   return created;
 }
  /** Build an processor. */
  public BBProcessor build() {
    this.createdScopes = new HashMap<Scope, ProcScope>();
    this.codes = new HashMap<Code, ProcCode>();
    this.constants = new HashMap<Constant, PatternConstant>();

    BBProcessor processor = new BBProcessor();
    processor.setScope(createScope(conf.getRootScope()));
    processor.setPrefix(createTemplate(conf.getPrefix()));
    processor.setSuffix(createTemplate(conf.getSuffix()));
    processor.setParams(conf.getParams());
    processor.setConstants(new HashSet<PatternConstant>(constants.values()));
    processor.setNestingLimit(conf.getNestingLimit());
    processor.setPropagateNestingException(conf.isPropagateNestingException());

    // Init scopes
    for (ProcScope scope : createdScopes.values()) {
      scope.init();
    }

    return processor;
  }