@NotNull
    private XPathType calcType() {
        final XPathElementType operator = getOperator();
        if (operator == XPathTokenTypes.UNION || XPath2TokenTypes.INTERSECT_EXCEPT.contains(operator)) {
            return XPathType.NODESET;
        } else if (XPath2TokenTypes.BOOLEAN_OPERATIONS.contains(operator)) {
            return XPathType.BOOLEAN;
        } else if (operator == XPath2TokenTypes.IDIV) {
            return XPath2Type.INTEGER;
        } else if (XPath2TokenTypes.NUMBER_OPERATIONS.contains(operator)) {
          final XPathExpression lop = getLOperand();
          final XPathExpression rop = getROperand();
          if (is(lop, XPathType.UNKNOWN) || is(rop, XPathType.UNKNOWN)) {
            return XPathType.UNKNOWN;
          }

          if (XPathTokenTypes.MUL_OPS.contains(operator)) {
            if (operator == XPathTokenTypes.DIV) {
              if (is(lop, XPath2Type.INTEGER) && is(rop, XPath2Type.INTEGER)) {
                return XPath2Type.DECIMAL;
              }
              return mostSpecificType(lop, rop, XPath2Type.NUMERIC);
            }

            if (is(lop, XPath2Type.DURATION)) {
              return lop.getType();
            } else if (is(rop, XPath2Type.DURATION)) {
              return lop != null ? rop.getType() : XPath2Type.DURATION;
            }

            return mostSpecificType(lop, rop, XPathType.NUMBER);
          } else {
            if (operator == XPathTokenTypes.PLUS) {
              if (is(lop, XPath2Type.DATE) || is(lop, XPath2Type.DATETIME) || is(lop, XPath2Type.TIME)) {
                if (is(rop, XPath2Type.DURATION)) {
                  return lop.getType();
                }
              } else if (is(rop, XPath2Type.DATE) || is(rop, XPath2Type.DATETIME) || is(rop, XPath2Type.TIME)) {
                if (is(lop, XPath2Type.DURATION)) {
                  return rop.getType();
                }
              }
            } else if (operator == XPathTokenTypes.MINUS) {
              if (is(lop, XPath2Type.DATE) || is(lop, XPath2Type.DATETIME) || is(lop, XPath2Type.TIME)) {
                if (is(rop, lop.getType())) {
                  return XPath2Type.DAYTIMEDURATION;
                }
                if (is(rop, XPath2Type.DURATION)) {
                  return lop.getType();
                }
              }
            }

            if (is(lop, XPath2Type.DURATION)) {
              return rop != null ? rop.getType() : XPathType.UNKNOWN;
            }
          }

          return mostSpecificType(lop, rop, XPathType.NUMBER);
        } else {
            return XPathType.UNKNOWN;
        }
    }
@NotNull
    private XPathType calcType()