int calculateWeight(FullTextQuery query) 
        { 
            switch (query.op) {
            case FullTextQuery.AND:
                {
                    return calculateWeight(((FullTextQueryBinaryOp)query).left);
                }
            case FullTextQuery.NEAR:
                {
                    int shift = STRICT_MATCH_BONUS;
                    for (FullTextQuery q = ((FullTextQueryBinaryOp)query).right; q.op == FullTextQuery.NEAR; q = ((FullTextQueryBinaryOp)q).right) { 
                        shift += STRICT_MATCH_BONUS;
                    }
                    return shift >= 32 ? 0 : (calculateWeight(((FullTextQueryBinaryOp)query).left) >> shift);
                }
            case FullTextQuery.OR:
                {
                    int leftWeight = calculateWeight(((FullTextQueryBinaryOp)query).left);
                    int rightWeight = calculateWeight(((FullTextQueryBinaryOp)query).right);
                    return leftWeight > rightWeight ? leftWeight : rightWeight;
                }
            case FullTextQuery.MATCH:
            case FullTextQuery.STRICT_MATCH:
                {
                    InverseList list = kwds[((FullTextQueryMatchOp)query).wno].list;
                    return list == null ? 0 : list.size();
                }
            default:
                return Integer.MAX_VALUE;
            }
        }