@Override
  public Object visit(DelphiPMDNode node, Object data) {
    String lookFor = getStringProperty(LOOK_FOR);
    if (StringUtils.isEmpty(lookFor)) {
      return data;
    }

    if (node.getText().equalsIgnoreCase(lookFor)) {
      Tree beginNode = null;
      for (int i = node.getChildIndex() + 1;
          i < node.getChildIndex() + MAX_LOOK_AHEAD && i < node.getParent().getChildCount();
          ++i) {
        if (node.getParent().getChild(i).getType() == DelphiLexer.BEGIN) {
          beginNode = node.getParent().getChild(i);
          break;
        }
      }
      if (beginNode != null) {
        boolean wasInherited = false;
        for (int c = 0; c < beginNode.getChildCount(); c++) {
          if (beginNode.getChild(c).getType() == DelphiLexer.INHERITED) {
            wasInherited = true;
            break;
          }
        }

        if (!wasInherited) {
          addViolation(data, node);
        }
      }
    }

    return data;
  }
  @Override
  public Object visit(DelphiPMDNode node, Object data) {
    if (node.getType() == DelphiLexer.PROCEDURE || node.getType() == DelphiLexer.FUNCTION) {
      Tree nameNode = node.getFirstChildWithType(DelphiLexer.TkFunctionName);
      if (nameNode != null) { // checking function name
        methodName = new StringBuilder(); // building function name
        for (int i = 0; i < nameNode.getChildCount(); ++i) {
          methodName.append(nameNode.getChild(i).getText());
        }
      }

      Tree argsNode = node.getFirstChildWithType(DelphiLexer.TkFunctionArgs);
      if (argsNode == null) {
        return data;
      }

      int lookIndex = 0;
      Tree beginNode = null; // looking for begin statement for function
      do {
        beginNode = node.getParent().getChild(node.getChildIndex() + (++lookIndex));
        if (lookIndex > MAX_LOOK_AHEAD || beginNode == null) {
          break;
        }
      } while (beginNode.getType() != DelphiLexer.BEGIN);

      if (beginNode == null || beginNode.getType() != DelphiLexer.BEGIN) {
        return data; // no begin..end for function
      }

      Map<String, Integer> args = processFunctionArgs(argsNode);
      if (args.isEmpty()) {
        return data; // no arguments
      }

      processFunctionBegin(beginNode, args);
      checkForUnusedArguments(args, data, node);
    }

    return data;
  }