@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;
  }
  /*
   * (non-Javadoc)
   * @see org.openl.binding.INodeBinder#bind(org.openl.parser.ISyntaxNode, org.openl.env.IOpenEnv,
   * org.openl.binding.IBindingContext)
   */
  public IBoundNode bind(ISyntaxNode node, IBindingContext bindingContext) throws Exception {

    if (node.getNumberOfChildren() != 1) {
      BindHelper.processError("Suffix node should have 1 subnode", node, bindingContext);

      return new ErrorBoundNode(node);
    }

    int index = node.getType().lastIndexOf('.');
    String methodName = node.getType().substring(index + 1);
    IBoundNode[] children = bindChildren(node, bindingContext);

    if (!children[0].isLvalue()) {
      BindHelper.processError(
          "The node is not an Lvalue", children[0].getSyntaxNode(), bindingContext, false);

      return new ErrorBoundNode(node);
    }

    IOpenClass[] types = getTypes(children);
    IMethodCaller methodCaller =
        UnaryOperatorNodeBinder.findUnaryOperatorMethodCaller(methodName, types, bindingContext);

    if (methodCaller == null) {

      String message = UnaryOperatorNodeBinder.errorMsg(methodName, types[0]);
      BindHelper.processError(message, node, bindingContext);

      return new ErrorBoundNode(node);
    }

    IOpenClass methodType = methodCaller.getMethod().getType();

    if (ClassUtils.primitiveToWrapper(methodType.getInstanceClass())
        != ClassUtils.primitiveToWrapper(types[0].getInstanceClass())) {
      //        if (!methodCaller.getMethod().getType().equals(types[0])) {
      BindHelper.processError(
          "Suffix operator must return the same type as an argument", node, bindingContext);

      return new ErrorBoundNode(node);
    }

    return new SuffixNode(node, children, methodCaller);
  }