// Path: src/main/java/immanix/matchers/NTimesMatcher.java
// public class NTimesMatcher<T> extends StaxMatcher<List<T>> {
//     private final StaxMatcher<T> delegate;
//     private int n;
// 
//     public NTimesMatcher(StaxMatcher<T> delegate, int n) {
//         this.delegate = delegate;
//         this.n = n;
// 
//     }
// 
//     @Override
//     public MatcherResult<List<T>> match(EventReader reader) throws XMLStreamException {
//         MatcherResult<List<T>> res = new AtMostMatcher<T>(delegate, n).match(reader);
//         if (res.isFailure()) {
//             return MatcherResult.failure(res.reader, res.errorMessage + "\n" + toString() + " failed due to the previous error");
//         } else {
//             if (res.data.size() < n) {
//                 return MatcherResult.failure(new BacktrackEventReader(res.consumedEvents, res.reader),
//                         toString() + " failed as the delegate matcher matched only " + res.data.size() + " time(s) instead of " + n);
//             } else {
//                 return res;
//             }
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return "(Times(" + n + ") " + delegate + ")";
//     }
// }
// 
// Path: src/main/java/immanix/readers/ReplayEventReader.java
// @SuppressWarnings("restriction")
// public class ReplayEventReader implements EventReader {
// 
//     private Iterator<? extends XMLEvent> events;
// 
//     public ReplayEventReader(List<? extends XMLEvent> events) {
//         super();
//         this.events = new ArrayList(events).iterator();
//     }
// 
//     public boolean hasNext() {
//         return events.hasNext();
//     }
// 
//     public XMLEvent next() throws XMLStreamException {
//         return events.next();
//     }
// 
//     public EventReader unwrap() {
//         return this;
//     }
// 
//     @Override
//     public String toString() {
//         return "Replayer";
//     }
// }
// 
// Path: src/test/java/immanix/utils/FullPacman.java
// public class FullPacman extends StaxMatcher<Object> {
//     int count;
// 
//     public FullPacman(int count) {
//         this.count = count;
//     }
// 
//     @Override
//     public MatcherResult<Object> match(EventReader reader) throws XMLStreamException {
//         if (count-- > 0) {
//             return MatcherResult.<Object>success("S", reader, Collections.EMPTY_LIST);
//         } else {
//             return MatcherResult.failure(reader, "Pacman is full");
//         }
//     }
// }
// 
// Path: src/test/java/immanix/utils/HungryPacman.java
// public class HungryPacman extends StaxMatcher<Object> {
//     int count;
// 
//     public HungryPacman(int count) {
//         this.count = count;
//     }
// 
//     @Override
//     public MatcherResult<Object> match(EventReader reader) throws XMLStreamException {
//         if (count-- > 0) {
//             return MatcherResult.<Object>success("S", reader, Arrays.asList(reader.next()));
//         } else {
//             return MatcherResult.failure(reader, "Pacman is full");
//         }
//     }
// }
// 
// Path: src/test/java/immanix/utils/XMLEventsUtils.java
// public static XMLEvent c(String val) {
//     return eventFactory.createCharacters(val);
// }


import org.junit.Test;
import immanix.matchers.NTimesMatcher;
import immanix.readers.ReplayEventReader;
import immanix.utils.FullPacman;
import immanix.utils.HungryPacman;
import javax.xml.stream.events.XMLEvent;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static immanix.utils.XMLEventsUtils.c;
        MatcherResult<List<Object>> res = sm.match(null);

        //must match
        assertFalse(res.isFailure());
        assertEquals(4, res.data.size());

        //this should suffice, as the interactions with the delegate matcher (and hence the reader are tested in  testDelegateMatcherIsCalledCorrectly)
    }

    @Test
    public void testFailureWhenLessThanTheWantedNumberOfMatchingsAreFound() throws Exception {
        StaxMatcher<Object> delegateMatcher = new FullPacman(2);


        NTimesMatcher<Object> m = new NTimesMatcher<Object>(delegateMatcher, 4);
        NTimesMatcher<Object> sm = spy(m);

        MatcherResult<List<Object>> res = sm.match(null);

        //must fail
        assertTrue(res.isFailure());

        //this should suffice, as the interactions with the delegate matcher (and hence the reader are tested in  testDelegateMatcherIsCalledCorrectly)
    }

    @Test
    public void testFailureWhenMoreThanTheWantedNumberOfMatchingsIsFound() throws Exception {
        StaxMatcher<Object> delegateMatcher = new FullPacman(4);

        NTimesMatcher<Object> m = new NTimesMatcher<Object>(delegateMatcher, 3);
// Path: src/main/java/immanix/matchers/NTimesMatcher.java
// public class NTimesMatcher<T> extends StaxMatcher<List<T>> {
//     private final StaxMatcher<T> delegate;
//     private int n;
// 
//     public NTimesMatcher(StaxMatcher<T> delegate, int n) {
//         this.delegate = delegate;
//         this.n = n;
// 
//     }
// 
//     @Override
//     public MatcherResult<List<T>> match(EventReader reader) throws XMLStreamException {
//         MatcherResult<List<T>> res = new AtMostMatcher<T>(delegate, n).match(reader);
//         if (res.isFailure()) {
//             return MatcherResult.failure(res.reader, res.errorMessage + "\n" + toString() + " failed due to the previous error");
//         } else {
//             if (res.data.size() < n) {
//                 return MatcherResult.failure(new BacktrackEventReader(res.consumedEvents, res.reader),
//                         toString() + " failed as the delegate matcher matched only " + res.data.size() + " time(s) instead of " + n);
//             } else {
//                 return res;
//             }
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return "(Times(" + n + ") " + delegate + ")";
//     }
// }
// 
// Path: src/main/java/immanix/readers/ReplayEventReader.java
// @SuppressWarnings("restriction")
// public class ReplayEventReader implements EventReader {
// 
//     private Iterator<? extends XMLEvent> events;
// 
//     public ReplayEventReader(List<? extends XMLEvent> events) {
//         super();
//         this.events = new ArrayList(events).iterator();
//     }
// 
//     public boolean hasNext() {
//         return events.hasNext();
//     }
// 
//     public XMLEvent next() throws XMLStreamException {
//         return events.next();
//     }
// 
//     public EventReader unwrap() {
//         return this;
//     }
// 
//     @Override
//     public String toString() {
//         return "Replayer";
//     }
// }
// 
// Path: src/test/java/immanix/utils/FullPacman.java
// public class FullPacman extends StaxMatcher<Object> {
//     int count;
// 
//     public FullPacman(int count) {
//         this.count = count;
//     }
// 
//     @Override
//     public MatcherResult<Object> match(EventReader reader) throws XMLStreamException {
//         if (count-- > 0) {
//             return MatcherResult.<Object>success("S", reader, Collections.EMPTY_LIST);
//         } else {
//             return MatcherResult.failure(reader, "Pacman is full");
//         }
//     }
// }
// 
// Path: src/test/java/immanix/utils/HungryPacman.java
// public class HungryPacman extends StaxMatcher<Object> {
//     int count;
// 
//     public HungryPacman(int count) {
//         this.count = count;
//     }
// 
//     @Override
//     public MatcherResult<Object> match(EventReader reader) throws XMLStreamException {
//         if (count-- > 0) {
//             return MatcherResult.<Object>success("S", reader, Arrays.asList(reader.next()));
//         } else {
//             return MatcherResult.failure(reader, "Pacman is full");
//         }
//     }
// }
// 
// Path: src/test/java/immanix/utils/XMLEventsUtils.java
// public static XMLEvent c(String val) {
//     return eventFactory.createCharacters(val);
// }


// Path: src/test/java/immanix/NTimesMatcherTest.java
import org.junit.Test;
import immanix.matchers.NTimesMatcher;
import immanix.readers.ReplayEventReader;
import immanix.utils.FullPacman;
import immanix.utils.HungryPacman;
import javax.xml.stream.events.XMLEvent;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static immanix.utils.XMLEventsUtils.c;

        MatcherResult<List<Object>> res = sm.match(null);

        //must match
        assertFalse(res.isFailure());
        assertEquals(4, res.data.size());

        //this should suffice, as the interactions with the delegate matcher (and hence the reader are tested in  testDelegateMatcherIsCalledCorrectly)
    }

    @Test
    public void testFailureWhenLessThanTheWantedNumberOfMatchingsAreFound() throws Exception {
        StaxMatcher<Object> delegateMatcher = new FullPacman(2);


        NTimesMatcher<Object> m = new NTimesMatcher<Object>(delegateMatcher, 4);
        NTimesMatcher<Object> sm = spy(m);

        MatcherResult<List<Object>> res = sm.match(null);

        //must fail
        assertTrue(res.isFailure());

        //this should suffice, as the interactions with the delegate matcher (and hence the reader are tested in  testDelegateMatcherIsCalledCorrectly)
    }

    @Test
    public void testFailureWhenMoreThanTheWantedNumberOfMatchingsIsFound() throws Exception {
        StaxMatcher<Object> delegateMatcher = new FullPacman(4);

        NTimesMatcher<Object> m = new NTimesMatcher<Object>(delegateMatcher, 3);
        NTimesMatcher<Object> sm = spy(m);