@Override
  public IBoundNode bindTarget(ISyntaxNode node, IBindingContext bindingContext, IBoundNode target)
      throws Exception {

    int childrenCount = node.getNumberOfChildren();

    if (childrenCount < 1) {
      BindHelper.processError("New node should have at least one subnode", node, bindingContext);

      return new ErrorBoundNode(node);
    }

    ISyntaxNode lastNode = node.getChild(childrenCount - 1);

    String methodName = ((IdentifierNode) lastNode).getIdentifier();

    IBoundNode[] children = bindChildren(node, bindingContext, 0, childrenCount - 1);
    IOpenClass[] types = getTypes(children);

    IMethodCaller methodCaller =
        MethodSearch.getMethodCaller(methodName, types, bindingContext, target.getType());

    if (methodCaller == null) {

      StringBuilder buf = new StringBuilder("Method ");
      MethodUtil.printMethod(methodName, types, buf);
      buf.append(" not found in '").append(target.getType().getName()).append("'");

      BindHelper.processError(buf.toString(), node, bindingContext, false);

      return new ErrorBoundNode(node);
    }

    if (target.isStaticTarget() != methodCaller.getMethod().isStatic()) {

      if (methodCaller.getMethod().isStatic()) {
        BindHelper.processWarn(
            "Access of a static method from non-static object", node, bindingContext);
      } else {
        BindHelper.processError(
            "Access of a non-static method from a static object", node, bindingContext);

        return new ErrorBoundNode(node);
      }
    }

    MethodBoundNode result = new MethodBoundNode(node, children, methodCaller, target);
    result.setTargetNode(target);

    return result;
  }