// Path: collection-matchers/src/main/java/ru/yandex/qatools/matchers/collection/MismatchHelper.java
// @SuppressWarnings("unchecked")
// public static void appendMismatch(Description mismatchDescription, String comment, Collection collectionToPrint) {
//     if (collectionToPrint.size() > 0) {
//         mismatchDescription.appendText("\n(").appendText(comment)
//                 .appendText(") [")
//                 .appendValue(collectionToPrint.size())
//                 .appendText("]:\n")
//                 .appendValueList("-> ", "\n-> ", "", collectionToPrint);
//     }
// }
// 
// Path: collection-matchers/src/main/java/ru/yandex/qatools/matchers/collection/MismatchHelper.java
// public static <T> StringConverter<Wrapper<T>> asStringWithFrequency(
//         final Collection<Wrapper<T>> actualList,
//         final Collection<Wrapper<T>> expectedList) {
// 
//     return new StringConverter<Wrapper<T>>() {
//         @Override
//         public String convert(Wrapper<T> nextExpected) {
//             return format("%s - expected [%d] times, but frequency was - [%d]",
//                     nextExpected, frequency(expectedList, nextExpected), frequency(actualList, nextExpected));
//         }
//     };
// }


import ch.lambdaj.collection.LambdaCollection;
import org.hamcrest.*;
import java.util.Collection;
import static ch.lambdaj.collection.LambdaCollections.with;
import static java.util.Collections.frequency;
import static org.hamcrest.Matchers.is;
import static ru.yandex.qatools.matchers.collection.MismatchHelper.appendMismatch;
import static ru.yandex.qatools.matchers.collection.MismatchHelper.asStringWithFrequency;
package ru.yandex.qatools.matchers.collection;




/**
 * Created with IntelliJ IDEA.
 * User: lanwen
 * Date: 09.05.13
 * Time: 14:21
 */
public class HasSameItemsAsCollectionMatcher<T> extends TypeSafeDiagnosingMatcher<Collection<? extends T>> {

    private Collection<? extends T> expect;
    @SuppressWarnings("unchecked")
    private WrapperFactory<T> wrapperFactory = (WrapperFactory<T>) ObjectMethodsWrapper.standardMethods();


    public HasSameItemsAsCollectionMatcher(Collection<? extends T> expected) {
        this.expect = expected;
    }


    @Override
    protected boolean matchesSafely(Collection<? extends T> actual, Description mismatchDescription) {
        LambdaCollection<Wrapper<T>> wrappedActual = with(actual).convert(WrapperConverter.wrapWith(wrapperFactory));
        LambdaCollection<Wrapper<T>> wrappedExpected = with(expect).convert(WrapperConverter.wrapWith(wrapperFactory));

        LambdaCollection<Wrapper<T>> frequencyNotEqual = wrappedExpected.clone()
                .remove(occurrCountEqual(wrappedActual, wrappedExpected));
        frequencyNotEqual.addAll(wrappedActual.clone().remove(occurrCountEqual(wrappedActual, wrappedExpected)));

// Path: collection-matchers/src/main/java/ru/yandex/qatools/matchers/collection/MismatchHelper.java
// @SuppressWarnings("unchecked")
// public static void appendMismatch(Description mismatchDescription, String comment, Collection collectionToPrint) {
//     if (collectionToPrint.size() > 0) {
//         mismatchDescription.appendText("\n(").appendText(comment)
//                 .appendText(") [")
//                 .appendValue(collectionToPrint.size())
//                 .appendText("]:\n")
//                 .appendValueList("-> ", "\n-> ", "", collectionToPrint);
//     }
// }
// 
// Path: collection-matchers/src/main/java/ru/yandex/qatools/matchers/collection/MismatchHelper.java
// public static <T> StringConverter<Wrapper<T>> asStringWithFrequency(
//         final Collection<Wrapper<T>> actualList,
//         final Collection<Wrapper<T>> expectedList) {
// 
//     return new StringConverter<Wrapper<T>>() {
//         @Override
//         public String convert(Wrapper<T> nextExpected) {
//             return format("%s - expected [%d] times, but frequency was - [%d]",
//                     nextExpected, frequency(expectedList, nextExpected), frequency(actualList, nextExpected));
//         }
//     };
// }


// Path: collection-matchers/src/main/java/ru/yandex/qatools/matchers/collection/HasSameItemsAsCollectionMatcher.java
import ch.lambdaj.collection.LambdaCollection;
import org.hamcrest.*;
import java.util.Collection;
import static ch.lambdaj.collection.LambdaCollections.with;
import static java.util.Collections.frequency;
import static org.hamcrest.Matchers.is;
import static ru.yandex.qatools.matchers.collection.MismatchHelper.appendMismatch;
import static ru.yandex.qatools.matchers.collection.MismatchHelper.asStringWithFrequency;

package ru.yandex.qatools.matchers.collection;




/**
 * Created with IntelliJ IDEA.
 * User: lanwen
 * Date: 09.05.13
 * Time: 14:21
 */
public class HasSameItemsAsCollectionMatcher<T> extends TypeSafeDiagnosingMatcher<Collection<? extends T>> {

    private Collection<? extends T> expect;
    @SuppressWarnings("unchecked")
    private WrapperFactory<T> wrapperFactory = (WrapperFactory<T>) ObjectMethodsWrapper.standardMethods();


    public HasSameItemsAsCollectionMatcher(Collection<? extends T> expected) {
        this.expect = expected;
    }


    @Override
    protected boolean matchesSafely(Collection<? extends T> actual, Description mismatchDescription) {
        LambdaCollection<Wrapper<T>> wrappedActual = with(actual).convert(WrapperConverter.wrapWith(wrapperFactory));
        LambdaCollection<Wrapper<T>> wrappedExpected = with(expect).convert(WrapperConverter.wrapWith(wrapperFactory));

        LambdaCollection<Wrapper<T>> frequencyNotEqual = wrappedExpected.clone()
                .remove(occurrCountEqual(wrappedActual, wrappedExpected));
        frequencyNotEqual.addAll(wrappedActual.clone().remove(occurrCountEqual(wrappedActual, wrappedExpected)));

        appendMismatch(mismatchDescription, "Not equal frequency",