// Path: src/main/java/nl/ulso/sprox/XmlProcessor.java
// public interface XmlProcessor<T> {
// 
//     /**
//      * Process XML by pulling it from a reader. The reader is not closed. If buffering is needed, this must be
//      * provided by the caller.
//      *
//      * @param reader The reader to pull the XML from.
//      * @return The result of processing the XML; is {@code null} only if {@code T} is {@link java.lang.Void}.
//      * @throws XmlProcessorException If an error occurred while processing the XML
//      */
//     T execute(Reader reader) throws XmlProcessorException;
// 
//     /**
//      * Process XML by pulling it from an input stream. The input stream is not closed. If buffering is needed, this
//      * must be provided by the caller.
//      *
//      * @param inputStream The stream to pull the XML from.
//      * @return The result of processing the XML; is {@code null} only if {@code T} is {@link java.lang.Void}.
//      * @throws XmlProcessorException If an error occurred while processing the XML
//      */
//     T execute(InputStream inputStream) throws XmlProcessorException;
// }
// 
// Path: src/main/java/nl/ulso/sprox/XmlProcessorBuilderFactory.java
// public interface XmlProcessorBuilderFactory {
//     <T> XmlProcessorBuilder<T> createXmlProcessorBuilder(Class<T> resultClass);
// }
// 
// Path: src/main/java/nl/ulso/sprox/impl/StaxBasedXmlProcessorBuilderFactory.java
// public class StaxBasedXmlProcessorBuilderFactory implements XmlProcessorBuilderFactory {
//     @Override
//     public <T> XmlProcessorBuilder<T> createXmlProcessorBuilder(Class<T> resultClass) {
//         return new StaxBasedXmlProcessorBuilder<>(resultClass);
//     }
// }
// 
// Path: src/test/java/nl/ulso/sprox/opml/OutlineFactoryTest.java
// public static int countElements(Outline outline) {
//     final ElementCounter counter = new ElementCounter();
//     outline.accept(counter);
//     return counter.count;
// }


import nl.ulso.sprox.XmlProcessor;
import nl.ulso.sprox.XmlProcessorBuilderFactory;
import nl.ulso.sprox.impl.StaxBasedXmlProcessorBuilderFactory;
import org.junit.Before;
import org.junit.Test;
import static nl.ulso.sprox.opml.OutlineFactoryTest.ElementCounter.countElements;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
    public void testOutlineFactory() throws Exception {
        final XmlProcessor<Outline> processor = factory.createXmlProcessorBuilder(Outline.class)
                .addControllerClass(OutlineFactory.class)
                .addParser(new Rfc822DateTimeParser())
                .buildXmlProcessor();
        final Outline outline = processor.execute(getClass().getResourceAsStream("/states.opml"));
        assertNotNull(outline);
        assertThat(outline.getTitle(), is("states.opml"));
        assertThat(countElements(outline), is(63));
        assertThat(outline.getNumberOfElements(), is(1));
        final Element unitedStates = outline.getElementAt(0);
        assertThat(unitedStates.getText(), is("United States"));
        assertThat(unitedStates.getNumberOfElements(), is(8));
    }

    static class ElementCounter implements Visitor {
        private int count = 0;

        private ElementCounter() {
        }

        @Override
        public void visit(Outline outline) {
        }

        @Override
        public void visit(Element element) {
            count++;
        }

// Path: src/main/java/nl/ulso/sprox/XmlProcessor.java
// public interface XmlProcessor<T> {
// 
//     /**
//      * Process XML by pulling it from a reader. The reader is not closed. If buffering is needed, this must be
//      * provided by the caller.
//      *
//      * @param reader The reader to pull the XML from.
//      * @return The result of processing the XML; is {@code null} only if {@code T} is {@link java.lang.Void}.
//      * @throws XmlProcessorException If an error occurred while processing the XML
//      */
//     T execute(Reader reader) throws XmlProcessorException;
// 
//     /**
//      * Process XML by pulling it from an input stream. The input stream is not closed. If buffering is needed, this
//      * must be provided by the caller.
//      *
//      * @param inputStream The stream to pull the XML from.
//      * @return The result of processing the XML; is {@code null} only if {@code T} is {@link java.lang.Void}.
//      * @throws XmlProcessorException If an error occurred while processing the XML
//      */
//     T execute(InputStream inputStream) throws XmlProcessorException;
// }
// 
// Path: src/main/java/nl/ulso/sprox/XmlProcessorBuilderFactory.java
// public interface XmlProcessorBuilderFactory {
//     <T> XmlProcessorBuilder<T> createXmlProcessorBuilder(Class<T> resultClass);
// }
// 
// Path: src/main/java/nl/ulso/sprox/impl/StaxBasedXmlProcessorBuilderFactory.java
// public class StaxBasedXmlProcessorBuilderFactory implements XmlProcessorBuilderFactory {
//     @Override
//     public <T> XmlProcessorBuilder<T> createXmlProcessorBuilder(Class<T> resultClass) {
//         return new StaxBasedXmlProcessorBuilder<>(resultClass);
//     }
// }
// 
// Path: src/test/java/nl/ulso/sprox/opml/OutlineFactoryTest.java
// public static int countElements(Outline outline) {
//     final ElementCounter counter = new ElementCounter();
//     outline.accept(counter);
//     return counter.count;
// }


// Path: src/test/java/nl/ulso/sprox/opml/OutlineFactoryTest.java
import nl.ulso.sprox.XmlProcessor;
import nl.ulso.sprox.XmlProcessorBuilderFactory;
import nl.ulso.sprox.impl.StaxBasedXmlProcessorBuilderFactory;
import org.junit.Before;
import org.junit.Test;
import static nl.ulso.sprox.opml.OutlineFactoryTest.ElementCounter.countElements;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

    public void testOutlineFactory() throws Exception {
        final XmlProcessor<Outline> processor = factory.createXmlProcessorBuilder(Outline.class)
                .addControllerClass(OutlineFactory.class)
                .addParser(new Rfc822DateTimeParser())
                .buildXmlProcessor();
        final Outline outline = processor.execute(getClass().getResourceAsStream("/states.opml"));
        assertNotNull(outline);
        assertThat(outline.getTitle(), is("states.opml"));
        assertThat(countElements(outline), is(63));
        assertThat(outline.getNumberOfElements(), is(1));
        final Element unitedStates = outline.getElementAt(0);
        assertThat(unitedStates.getText(), is("United States"));
        assertThat(unitedStates.getNumberOfElements(), is(8));
    }

    static class ElementCounter implements Visitor {
        private int count = 0;

        private ElementCounter() {
        }

        @Override
        public void visit(Outline outline) {
        }

        @Override
        public void visit(Element element) {
            count++;
        }

        public static int countElements(Outline outline) {