public SearchQuery parse(@NotNull String query) {
        SearchQuery searchQuery = new SearchQuery();

        StringTokenizer tokenizer = new StringTokenizer(initialProcess(query), DELIMITERS, false);

        Term prevTerm = null;
        boolean waitingForOperand = true;
        while (tokenizer.hasMoreTokens()) {
            Term term = TermImpl.create(tokenizer.nextToken());
            if (waitingForOperand) {
                matchOperand(term);

                if (prevTerm != null) {
                    extendQuery(searchQuery, (Operator) prevTerm, term);
                } else {
                    searchQuery.single(term);
                }

                waitingForOperand = false;
            } else {
                matchOperator(term);

                waitingForOperand = true;
            }

            prevTerm = term;
        }

        if (waitingForOperand) {
            throw new ErrorParsingException(EXPECTED_OPERAND_ERROR_MESSAGE);
        }

        return searchQuery;
    }