// Path: src/com/googlecode/yatspec/state/givenwhenthen/CapturedInputAndOutputs.java
// public class CapturedInputAndOutputs extends NiceMap<CapturedInputAndOutputs>{
//     public CapturedInputAndOutputs(Object... instances) {
//         super(instances);
//     }
// }
// 
// Path: src/com/googlecode/yatspec/plugin/jdom/StateExtractors.java
// public static StateExtractor<String> getXpathValue(final String key, final String xpath) {
//     return new StateExtractor<String>() {
//         public String execute(CapturedInputAndOutputs capturedInputAndOutputs) throws Exception {
//             return getXpathValues(capturedInputAndOutputs, key, xpath).get(0);
//         }
//     };
// }
// 
// Path: src/com/googlecode/yatspec/plugin/jdom/StateExtractors.java
// public static StateExtractor<List<String>> getXpathValues(final String key, final String xpath) {
//     return new StateExtractor<List<String>>() {
//         public List<String> execute(CapturedInputAndOutputs capturedInputAndOutputs) throws Exception {
//             return getXpathValues(capturedInputAndOutputs, key, xpath);
//         }
//     };
// }


import com.googlecode.yatspec.state.givenwhenthen.CapturedInputAndOutputs;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collection;
import static com.googlecode.yatspec.plugin.jdom.StateExtractors.getXpathValue;
import static com.googlecode.yatspec.plugin.jdom.StateExtractors.getXpathValues;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsCollectionContaining.hasItem;
        Document document =  document("<People><Person><Name>" + NAME + "</Name></Person></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValue(KEY, "//People/Person/Name").execute(inputAndOutputs), is(NAME));
    }

    @Test
    public void shouldExtractMultipleSiblingXPathElements() throws Exception {
        Document document =  document("<People><Person>"+"<Name>" + NAME + "</Name>"+"<Name>" + ANOTHER_NAME + "</Name>"+"</Person></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(StateExtractors.getXpathValues(KEY, "//People/Person/Name").execute(inputAndOutputs), is(asList(NAME, ANOTHER_NAME)));
    }

    @Test
    public void shouldExtractXpathAttribute() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValue(KEY, "//People/Person/@Name").execute(inputAndOutputs), is(NAME));
    }

    @Test
    public void shouldExtractSiblingXpathAttribute() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/><Person Name=\"" + ANOTHER_NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValues(KEY, "//People/Person/@Name").execute(inputAndOutputs), is(asList(NAME, ANOTHER_NAME)));
    }

    @Test(expected=IllegalStateException.class)
    public void shouldThrowExceptionWhenXPathIsNotFound() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
// Path: src/com/googlecode/yatspec/state/givenwhenthen/CapturedInputAndOutputs.java
// public class CapturedInputAndOutputs extends NiceMap<CapturedInputAndOutputs>{
//     public CapturedInputAndOutputs(Object... instances) {
//         super(instances);
//     }
// }
// 
// Path: src/com/googlecode/yatspec/plugin/jdom/StateExtractors.java
// public static StateExtractor<String> getXpathValue(final String key, final String xpath) {
//     return new StateExtractor<String>() {
//         public String execute(CapturedInputAndOutputs capturedInputAndOutputs) throws Exception {
//             return getXpathValues(capturedInputAndOutputs, key, xpath).get(0);
//         }
//     };
// }
// 
// Path: src/com/googlecode/yatspec/plugin/jdom/StateExtractors.java
// public static StateExtractor<List<String>> getXpathValues(final String key, final String xpath) {
//     return new StateExtractor<List<String>>() {
//         public List<String> execute(CapturedInputAndOutputs capturedInputAndOutputs) throws Exception {
//             return getXpathValues(capturedInputAndOutputs, key, xpath);
//         }
//     };
// }


// Path: test/com/googlecode/yatspec/plugin/jdom/StateExtractorsTest.java
import com.googlecode.yatspec.state.givenwhenthen.CapturedInputAndOutputs;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collection;
import static com.googlecode.yatspec.plugin.jdom.StateExtractors.getXpathValue;
import static com.googlecode.yatspec.plugin.jdom.StateExtractors.getXpathValues;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsCollectionContaining.hasItem;

        Document document =  document("<People><Person><Name>" + NAME + "</Name></Person></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValue(KEY, "//People/Person/Name").execute(inputAndOutputs), is(NAME));
    }

    @Test
    public void shouldExtractMultipleSiblingXPathElements() throws Exception {
        Document document =  document("<People><Person>"+"<Name>" + NAME + "</Name>"+"<Name>" + ANOTHER_NAME + "</Name>"+"</Person></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(StateExtractors.getXpathValues(KEY, "//People/Person/Name").execute(inputAndOutputs), is(asList(NAME, ANOTHER_NAME)));
    }

    @Test
    public void shouldExtractXpathAttribute() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValue(KEY, "//People/Person/@Name").execute(inputAndOutputs), is(NAME));
    }

    @Test
    public void shouldExtractSiblingXpathAttribute() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/><Person Name=\"" + ANOTHER_NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        assertThat(getXpathValues(KEY, "//People/Person/@Name").execute(inputAndOutputs), is(asList(NAME, ANOTHER_NAME)));
    }

    @Test(expected=IllegalStateException.class)
    public void shouldThrowExceptionWhenXPathIsNotFound() throws Exception {
        Document document = document("<People><Person Name=\"" + NAME + "\"/></People>");
        CapturedInputAndOutputs inputAndOutputs = new CapturedInputAndOutputs().add(KEY, document);
        getXpathValue(KEY, "//doesNotExist").execute(inputAndOutputs);