package com.bbn.kbp.events2014;

import com.bbn.bue.common.symbols.Symbol;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.*;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.compose;
import static com.google.common.base.Predicates.in;
import static com.google.common.collect.Iterables.concat;

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);
        checkValidity();
    }

    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());
    }

    /**
     * Creates a response linking with containing all responses from the given
     * answer key which are correct (up to justifications) and have CASes
     * with coref annotations.  These will all be marked as 'incomplete'.
     */
    public static ResponseLinking createUnlinkedFor(AnswerKey answerKey) {
        final Predicate<Response> CASHasBeenCoreffed =
                compose(in(answerKey.corefAnnotation().annotatedCASes()),
                        Response.CASFunction());

        final ImmutableSet<Response> linkingCandidates = FluentIterable
                .from(answerKey.annotatedResponses())
                .filter(AssessedResponse.IsCorrectUpToInexactJustifications)
                .transform(AssessedResponse.Response)
                .filter(CASHasBeenCoreffed)
                .toSet();

        return from(answerKey.docId(), ImmutableSet.<ResponseSet>of(),
                        Iterables.transform(answerKey.annotatedResponses(), AssessedResponse.Response));
    }

    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);
    }

    private void checkValidity() {
        // no incomplete response may appear in any response set
        final ImmutableSet<Response> allResponsesInSets = ImmutableSet.copyOf(
                concat(responseSets));
        for (final Response incompleteResponse : incompleteResponses) {
            checkArgument(!allResponsesInSets.contains(incompleteResponse),
                    "A response may not be both completed and incomplete");
        }
    }

    public ImmutableSet<Response> allResponses() {
        return ImmutableSet.copyOf(concat(concat(responseSets), incompleteResponses));
    }
}

@@ -132,30 +132,84 @@
 .common.
-base.Predicate
+collect.ImmutableList;%0Aimport com.google.common.collect.ImmutableSet
 ;%0Aimport
@@ -235,17 +235,34 @@
 collect.
-*
+ImmutableSortedSet
 ;%0A%0Aimpor
@@ -391,117 +391,8 @@
 ll;%0A
-import static com.google.common.base.Predicates.compose;%0Aimport static com.google.common.base.Predicates.in;%0A
 impo
@@ -1479,1015 +1479,8 @@
  %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   

Remove unused method which looks broken anyway