protected Expression unary() throws ParsingException {
        char nextChar = getChar();
        if (Character.isLetter(nextChar) || Character.isDigit(nextChar)) {
            return predicate(Character.isUpperCase(nextChar));
        } else if (nextChar == '!') {
            return new Not(unary());
        } else if (nextChar == '(') {
            int saveIndex = index;
            Expression result;
            try {
                result = implication();
                if (getChar() != ')')
                    throw new ParsingException("cannot parse: " + expression);
            } catch (ParsingException pe) {
                index = saveIndex;
                result = predicate(false);
            }
            return result;
        } else if (nextChar == '@') {
            {

                return new ForAll(variable(), unary());
            }
        } else if (nextChar == '?') {
            return new Exists(variable(), unary());
        } else {
            throw new ParsingException("cannot parse: " + expression);
        }
    }