docs: @SuppressWarnings("unchecked")
    @Override
    protected void initParser() throws MtasConfigException {
      super.initParser();
      if (config != null) {
        // always word, no mappings
        wordType = new MtasParserType<>(MAPPING_TYPE_WORD, null, false);
        for (int i = 0; i < config.children.size(); i++) {
          MtasConfiguration current = config.children.get(i);
          if (current.name.equals("filters")) {
            for (int j = 0; j < current.children.size(); j++) {
              if (current.children.get(j).name.equals("filter")) {
                MtasConfiguration filter = current.children.get(j);
                String typeFilter = filter.attributes.get("type");
                String nameFilter = filter.attributes.get("name");
                if(typeFilter!=null) {
                  if(typeFilter.equals(FILTER_TYPE_REPLACE)) {
                    String value = filter.attributes.get("value");
                    String replace = filter.attributes.get("replace");
                    if(nameFilter!=null && value!=null && replace!=null) {
                      String[] names = nameFilter.split(Pattern.quote(","));
                      for(String name : names) {
                        try {
                          int nameInt = Integer.parseInt(name);
                          HashMap<String, String> nameMap;
                          if(!filterReplace.containsKey(nameInt)) {
                            nameMap = new HashMap<>();
                            filterReplace.put(nameInt, nameMap);
                          } else {
                            nameMap = filterReplace.get(nameInt);
                          }
                          nameMap.put(value, replace);
                        } catch (NumberFormatException e) {
                          log.info(e);                        
                        }                      
                      }                    
                    } else {
                      throw new MtasConfigException("no name, value or replace for filter "
                          + typeFilter );
                    }
                  } else {
                    throw new MtasConfigException("unknown filter type "
                        + typeFilter );
                  }
                } else {
                  throw new MtasConfigException("no type provided for filter" );
                }
              }
            }  
          } else if (current.name.equals("mappings")) {
            for (int j = 0; j < current.children.size(); j++) {
              if (current.children.get(j).name.equals("mapping")) {
                MtasConfiguration mapping = current.children.get(j);
                String typeMapping = mapping.attributes.get("type");
                String nameMapping = mapping.attributes.get("name");
                if ((typeMapping != null)) {
                  if (typeMapping.equals(MAPPING_TYPE_WORD)) {
                    MtasCRMParserMappingWordAnnotation m = new MtasCRMParserMappingWordAnnotation();
                    m.processConfig(mapping);
                    wordType.addItem(m);
                  } else if (typeMapping.equals(MAPPING_TYPE_WORD_ANNOTATION)
                      && (nameMapping != null)) {
                    MtasCRMParserMappingWordAnnotation m = new MtasCRMParserMappingWordAnnotation();
                    m.processConfig(mapping);
                    if (wordAnnotationTypes.containsKey(nameMapping)) {
                      wordAnnotationTypes.get(nameMapping).addItem(m);
                    } else {
                      MtasParserType<MtasParserMapping<?>> t = new MtasParserType<>(
                          typeMapping, nameMapping, false);
                      t.addItem(m);
                      wordAnnotationTypes.put(nameMapping, t);
                    }
                  } else if (typeMapping.equals(MAPPING_TYPE_CRM_SENTENCE)) {
                    MtasCRMParserMappingCRMSentence m = new MtasCRMParserMappingCRMSentence();
                    m.processConfig(mapping);
                    if (crmSentenceTypes.containsKey(nameMapping)) {
                      crmSentenceTypes.get(nameMapping).addItem(m);
                    } else {
                      MtasParserType<MtasParserMapping<?>> t = new MtasParserType<>(
                          MAPPING_TYPE_GROUP, nameMapping, true);
                      t.addItem(m);
                      crmSentenceTypes.put(nameMapping, t);
                    }
                  } else if (typeMapping.equals(MAPPING_TYPE_CRM_CLAUSE)) {
                    MtasCRMParserMappingCRMSentence m = new MtasCRMParserMappingCRMSentence();
                    m.processConfig(mapping);
                    if (crmClauseTypes.containsKey(nameMapping)) {
                      crmClauseTypes.get(nameMapping).addItem(m);
                    } else {
                      MtasParserType<MtasParserMapping<?>> t = new MtasParserType<>(
                          MAPPING_TYPE_GROUP, nameMapping, true);
                      t.addItem(m);
                      crmClauseTypes.put(nameMapping, t);
                    }
                  } else if (typeMapping.equals(MAPPING_TYPE_CRM_PAIR)) {
                    MtasCRMParserMappingCRMPair m = new MtasCRMParserMappingCRMPair();
                    m.processConfig(mapping);
                    if (crmPairTypes.containsKey(nameMapping)) {
                      crmPairTypes.get(nameMapping).addItem(m);
                    } else {
                      MtasParserType<MtasParserMapping<?>> t = new MtasParserType<>(
                          MAPPING_TYPE_RELATION, nameMapping, true);
                      t.addItem(m);
                      crmPairTypes.put(nameMapping, t);
                    }
                  } else {
                    throw new MtasConfigException("unknown mapping type "
                        + typeMapping + " or missing name");
                  }
                }
              }
            }
          } else if (current.name.equals("functions")) {
            for (int j = 0; j < current.children.size(); j++) {
              if (current.children.get(j).name.equals("function")) {
                MtasConfiguration function = current.children.get(j);
                String nameFunction = function.attributes.get("name");
                String typeFunction = function.attributes.get("type");
                String splitFunction = function.attributes.get("split");
                if (nameFunction != null && typeFunction != null) {
                  MtasCRMParserFunction mtasCRMParserFunction = new MtasCRMParserFunction(
                      typeFunction, splitFunction);
                  if (!functions.containsKey(typeFunction)) {
                    functions.put(typeFunction,
                        new HashMap<String, MtasCRMParserFunction>());
                  }
                  functions.get(typeFunction).put(nameFunction,
                      mtasCRMParserFunction);
                  MtasConfiguration subCurrent = current.children.get(j);
                  for (int k = 0; k < subCurrent.children.size(); k++) {
                    if (subCurrent.children.get(k).name.equals("condition")) {
                      MtasConfiguration subSubCurrent = subCurrent.children
                          .get(k);
                      if (subSubCurrent.attributes.containsKey("value")) {
                        String[] valuesCondition = subSubCurrent.attributes
                            .get("value").split(Pattern.quote(","));
                        ArrayList<MtasCRMParserFunctionOutput> valueOutputList = new ArrayList<>();
                        for (int l = 0; l < subSubCurrent.children.size(); l++) {
                          if (subSubCurrent.children.get(l).name
                              .equals("output")) {
                            String valueOutput = subSubCurrent.children
                                .get(l).attributes.get("value");
                            String nameOutput = subSubCurrent.children
                                .get(l).attributes.get("name");
                            if (nameOutput != null) {
                              MtasCRMParserFunctionOutput o = new MtasCRMParserFunctionOutput(
                                  nameOutput, valueOutput);
                              valueOutputList.add(o);
                            }
                          }
                        }
                        if (!valueOutputList.isEmpty()) {
                          for (String valueCondition : valuesCondition) {
                            if (mtasCRMParserFunction.output
                                .containsKey(valueCondition)) {
                              mtasCRMParserFunction.output.get(valueCondition)
                                  .addAll(
                                      (Collection<? extends MtasCRMParserFunctionOutput>) valueOutputList
                                          .clone());
                            } else {
                              mtasCRMParserFunction.output.put(valueCondition,
                                  (ArrayList<MtasCRMParserFunctionOutput>) valueOutputList
                                      .clone());
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }