public double proximity(CharSequence cSeq1, CharSequence cSeq2) {
        // really only need to create one of these; other can just it and add
        ObjectToCounterMap<String> tf1 = termFrequencyVector(cSeq1);
        ObjectToCounterMap<String> tf2 = termFrequencyVector(cSeq2);
        double len1 = 0.0;
        double len2 = 0.0;
        double prod = 0.0;
        for (Map.Entry<String,Counter> entry : tf1.entrySet()) {
            String term = entry.getKey();
            Counter count1 = entry.getValue();
            double tfIdf1 = tfIdf(term,count1);
            len1 += tfIdf1 * tfIdf1;
            Counter count2 = tf2.remove(term);
            if (count2 == null) continue;
            double tfIdf2 = tfIdf(term,count2);
            len2 += tfIdf2 * tfIdf2;
            prod += tfIdf1 * tfIdf2;
        }
        // increment length for terms in cSeq2 but not in cSeq1
        for (Map.Entry<String,Counter> entry : tf2.entrySet()) {
            String term = entry.getKey();
            Counter count2 = entry.getValue();
            double tfIdf2 = tfIdf(term,count2);
            len2 += tfIdf2 * tfIdf2;
        }
        if (len1 == 0)
            return len2 == 0.0 ? 1.0 : 0.0;
        if (len2 == 0) return 0.0;
        double prox = prod / Math.sqrt(len1 * len2);
        return prox < 0.0 
            ? 0.0
            : (prox > 1.0
               ? 1.0
               : prox);
    }