package com.bbn.kbp.events2014;

import com.bbn.bue.common.symbols.Symbol;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;

import static com.google.common.base.Preconditions.checkNotNull;

public class ResponseLinking {
    private final Symbol docId;
    private final ImmutableSet<ResponseSet> responseSets;
    private final ImmutableSet<Response> incompleteResponses;

    private ResponseLinking(Symbol docId, Iterable<ResponseSet> responseSets,
                            Iterable<Response> incompleteResponses)
    {
        this.docId = checkNotNull(docId);
        this.responseSets = ImmutableSortedSet.copyOf(responseSets);
        this.incompleteResponses = ImmutableSortedSet.copyOf(
                Response.byUniqueIdOrdering(), incompleteResponses);
    }

    public static ResponseLinking from(Symbol docId, Iterable<ResponseSet> responseSets,
                                       Iterable<Response> incompleteResponses)
    {
        return new ResponseLinking(docId, responseSets, incompleteResponses);
    }

    public static ResponseLinking createEmpty(Symbol docId) {
        return from(docId, ImmutableList.<ResponseSet>of(), ImmutableList.<Response>of());
    }

    public Symbol docID() {
        return docId;
    }

    public ImmutableSet<ResponseSet> responseSets() {
        return responseSets;
    }

    public ImmutableSet<Response> incompleteResponses() {
        return incompleteResponses;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(docId, responseSets, incompleteResponses);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final ResponseLinking other = (ResponseLinking) obj;
        return Objects.equal(this.docId, other.docId)
                && Objects.equal(this.responseSets, other.responseSets)
                && Objects.equal(this.incompleteResponses, incompleteResponses);
    }
}

@@ -136,29 +136,22 @@
 mon.
-collect.ImmutableList
+base.Predicate
 ;%0Aim
@@ -181,28 +181,74 @@
 collect.
-ImmutableSet
+*;%0Aimport static com.google.common.base.Predicates.compose
 ;%0Aimport
@@ -240,32 +240,39 @@
 compose;%0Aimport 
+static 
 com.google.commo
@@ -277,37 +277,95 @@
 mon.
-collect.ImmutableSortedSe
+base.Predicates.in;%0A%0Aimport static com.google.common.base.Preconditions.checkArgumen
 t;%0A
-%0A
 impo
@@ -996,32 +996,57 @@
 leteResponses);%0A
+        checkValidity();%0A
     %7D%0A%0A    publi
@@ -1447,32 +1447,1040 @@
 e%3Eof());%0A    %7D%0A%0A
+    /**%0A     * Creates a response linking with containing all responses from the given%0A     * answer key which are correct (up to justifications) and have CASes%0A     * with coref annotations.  These will all be marked as 'incomplete'.%0A     */%0A    public static ResponseLinking createUnlinkedFor(AnswerKey answerKey) %7B%0A        final Predicate%3CResponse%3E CASHasBeenCoreffed =%0A                compose(in(answerKey.corefAnnotation().annotatedCASes()),%0A                        Response.CASFunction());%0A%0A        final ImmutableSet%3CResponse%3E linkingCandidates = FluentIterable%0A                .from(answerKey.annotatedResponses())%0A                .filter(AssessedResponse.IsCorrectUpToInexactJustifications)%0A                .transform(AssessedResponse.Response)%0A                .filter(CASHasBeenCoreffed)%0A                .toSet();%0A%0A        return from(answerKey.docId(), ImmutableSet.%3CResponseSet%3Eof(),%0A                        Iterables.transform(answerKey.annotatedResponses(), AssessedResponse.Response));%0A    %7D%0A%0A
     public Symbo
@@ -3319,11 +3319,480 @@
 );%0A    %7D
+%0A%0A    private void checkValidity() %7B%0A        // no incomplete response may appear in any response set%0A        final ImmutableSet%3CResponse%3E allResponsesInSets = ImmutableSet.copyOf(%0A                Iterables.concat(responseSets));%0A        for (final Response incompleteResponse : incompleteResponses) %7B%0A            checkArgument(!allResponsesInSets.contains(incompleteResponse),%0A                    %22A response may not be both completed and incomplete%22);%0A        %7D%0A    %7D
 %0A%7D%0A

Create incomplete ResponseLinking from AnswerKey