// Path: src/main/java/com/difference/historybook/index/Index.java
// public interface Index extends AutoCloseable {
// 	/**
// 	 * Adds a given page to an index collection
// 	 * 
// 	 * @param collection      a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param url             the url of the page being indexed
// 	 * @param timestamp       the timestamp representing when the page was retrieved
// 	 * @param body            the textual content of the page (binaries are unsupported)
// 	 * @throws IndexException
// 	 */
// 	public void indexPage(String collection, String url, Instant timestamp, String body) throws IndexException;
// 	
// 	/**
// 	 * Executes a given query against the index in the specified collection namespace and returns up to the requested page size of results.
// 	 * 
// 	 * @param collection        a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param query             the search query to execute. The supported syntax of this is determined by the underlying @Index implementation
// 	 * @param offset            the 0-based offset to begin retrieving results from. Specifying an offset greater than the actual number of results will result in an empty result.
// 	 * @param size              the maximum number of results to return. The actual number of results returned may be fewer.
// 	 * @return                  the search results for the specified query along with relevant metadata.
// 	 * @see SearchResultWrapper
// 	 * @throws IndexException
// 	 */
// 	default public SearchResultWrapper search(String collection, String query, int offset, int size) throws IndexException {
// 		return search(collection, query, offset, size, false);
// 	}
// 
// 	/**
// 	 * Executes a given query against the index in the specified collection namespace and returns up to the requested page size of results.
// 	 * 
// 	 * @param collection        a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param query             the search query to execute. The supported syntax of this is determined by the underlying @Index implementation
// 	 * @param offset            the 0-based offset to begin retrieving results from. Specifying an offset greater than the actual number of results will result in an empty result.
// 	 * @param size              the maximum number of results to return. The actual number of results returned may be fewer.
// 	 * @param includeDebug		include implementation dependent debug information for search result
// 	 * @return                  the search results for the specified query along with relevant metadata.
// 	 * @see SearchResultWrapper
// 	 * @throws IndexException
// 	 */
// 	public SearchResultWrapper search(String collection, String query, int offset, int size, boolean includeDebug) throws IndexException;
// }
// 
// Path: src/main/java/com/difference/historybook/index/IndexException.java
// public class IndexException extends Exception {
// 	private static final long serialVersionUID = -1660541057609982084L;
// 
// 	public IndexException(String msg) {
// 		super(msg);
// 	}
// 	
// 	public IndexException(Exception e) {
// 		super(e);
// 	}
// }
// 
// Path: src/main/java/com/difference/historybook/index/SearchResultWrapper.java
// public class SearchResultWrapper {
// 	private String query;
// 	private int offset;
// 	private int maxResultsRequested;
// 	private int resultCount;
// 	private String debugInfo;
// 	private List<SearchResult> results;
// 
// 	public String getQuery() {
// 		return query;
// 	}
// 
// 	public SearchResultWrapper setQuery(String query) {
// 		this.query = query;
// 		return this;
// 	}
// 
// 	public int getOffset() {
// 		return offset;
// 	}
// 
// 	public SearchResultWrapper setOffset(int offset) {
// 		this.offset = offset;
// 		return this;
// 	}
// 
// 	public int getMaxResultsRequested() {
// 		return maxResultsRequested;
// 	}
// 
// 	public SearchResultWrapper setMaxResultsRequested(int maxResultsRequested) {
// 		this.maxResultsRequested = maxResultsRequested;
// 		return this;
// 	}
// 
// 	public int getResultCount() {
// 		return resultCount;
// 	}
// 
// 	public SearchResultWrapper setResultCount(int resultCount) {
// 		this.resultCount = resultCount;
// 		return this;
// 	}
// 
// 	public List<SearchResult> getResults() {
// 		return results;
// 	}
// 
// 	public SearchResultWrapper setResults(List<SearchResult> results) {
// 		this.results = results;
// 		return this;
// 	}
// 
// 	public String getDebugInfo() {
// 		return debugInfo;
// 	}
// 
// 	public SearchResultWrapper setDebugInfo(String debugInfo) {
// 		this.debugInfo = debugInfo;
// 		return this;
// 	}
// 	
// }


import com.difference.historybook.index.Index;
import com.difference.historybook.index.IndexException;
import com.difference.historybook.index.SearchResultWrapper;
import java.time.Instant;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
			) throws IndexException {
		LOG.debug("Received: {} {} {}", collection, url, timestamp.toString());
		index.indexPage(collection, url, timestamp, body);
		return Response.accepted().build(); //TODO: What is the correct response code?
	}
	
	//TODO: support date range queries

	/**
	 * Execute a search against the index
	 * 
	 * @param collection the namespaced collection to search within
	 * @param query the query to pass to the index
	 * @param offsetString 0 based offset within the search results (used for paging)
	 * @param sizeString maximum number of results to return
	 * @return the search results within a metadata wrapper
	 * @see Response
	 * @throws NumberFormatException
	 * @throws IndexException
	 */
	@GET
	@Produces("application/json")
	public Response getSearchResult(
			@PathParam("collection") String collection,
			@QueryParam("q") String query,
			@QueryParam("offset") @DefaultValue("0") String offsetString,
			@QueryParam("size") @DefaultValue("10") String sizeString,
			@QueryParam("debug") @DefaultValue("false") boolean debugFlag
			) throws NumberFormatException, IndexException {
		LOG.debug("Query: {} query:{} offset:{} size:{} debug:{}", collection, query, offsetString, sizeString, debugFlag);
// Path: src/main/java/com/difference/historybook/index/Index.java
// public interface Index extends AutoCloseable {
// 	/**
// 	 * Adds a given page to an index collection
// 	 * 
// 	 * @param collection      a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param url             the url of the page being indexed
// 	 * @param timestamp       the timestamp representing when the page was retrieved
// 	 * @param body            the textual content of the page (binaries are unsupported)
// 	 * @throws IndexException
// 	 */
// 	public void indexPage(String collection, String url, Instant timestamp, String body) throws IndexException;
// 	
// 	/**
// 	 * Executes a given query against the index in the specified collection namespace and returns up to the requested page size of results.
// 	 * 
// 	 * @param collection        a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param query             the search query to execute. The supported syntax of this is determined by the underlying @Index implementation
// 	 * @param offset            the 0-based offset to begin retrieving results from. Specifying an offset greater than the actual number of results will result in an empty result.
// 	 * @param size              the maximum number of results to return. The actual number of results returned may be fewer.
// 	 * @return                  the search results for the specified query along with relevant metadata.
// 	 * @see SearchResultWrapper
// 	 * @throws IndexException
// 	 */
// 	default public SearchResultWrapper search(String collection, String query, int offset, int size) throws IndexException {
// 		return search(collection, query, offset, size, false);
// 	}
// 
// 	/**
// 	 * Executes a given query against the index in the specified collection namespace and returns up to the requested page size of results.
// 	 * 
// 	 * @param collection        a namespace for an index. Allows storing multiple indexes within the same backing store.
// 	 * @param query             the search query to execute. The supported syntax of this is determined by the underlying @Index implementation
// 	 * @param offset            the 0-based offset to begin retrieving results from. Specifying an offset greater than the actual number of results will result in an empty result.
// 	 * @param size              the maximum number of results to return. The actual number of results returned may be fewer.
// 	 * @param includeDebug		include implementation dependent debug information for search result
// 	 * @return                  the search results for the specified query along with relevant metadata.
// 	 * @see SearchResultWrapper
// 	 * @throws IndexException
// 	 */
// 	public SearchResultWrapper search(String collection, String query, int offset, int size, boolean includeDebug) throws IndexException;
// }
// 
// Path: src/main/java/com/difference/historybook/index/IndexException.java
// public class IndexException extends Exception {
// 	private static final long serialVersionUID = -1660541057609982084L;
// 
// 	public IndexException(String msg) {
// 		super(msg);
// 	}
// 	
// 	public IndexException(Exception e) {
// 		super(e);
// 	}
// }
// 
// Path: src/main/java/com/difference/historybook/index/SearchResultWrapper.java
// public class SearchResultWrapper {
// 	private String query;
// 	private int offset;
// 	private int maxResultsRequested;
// 	private int resultCount;
// 	private String debugInfo;
// 	private List<SearchResult> results;
// 
// 	public String getQuery() {
// 		return query;
// 	}
// 
// 	public SearchResultWrapper setQuery(String query) {
// 		this.query = query;
// 		return this;
// 	}
// 
// 	public int getOffset() {
// 		return offset;
// 	}
// 
// 	public SearchResultWrapper setOffset(int offset) {
// 		this.offset = offset;
// 		return this;
// 	}
// 
// 	public int getMaxResultsRequested() {
// 		return maxResultsRequested;
// 	}
// 
// 	public SearchResultWrapper setMaxResultsRequested(int maxResultsRequested) {
// 		this.maxResultsRequested = maxResultsRequested;
// 		return this;
// 	}
// 
// 	public int getResultCount() {
// 		return resultCount;
// 	}
// 
// 	public SearchResultWrapper setResultCount(int resultCount) {
// 		this.resultCount = resultCount;
// 		return this;
// 	}
// 
// 	public List<SearchResult> getResults() {
// 		return results;
// 	}
// 
// 	public SearchResultWrapper setResults(List<SearchResult> results) {
// 		this.results = results;
// 		return this;
// 	}
// 
// 	public String getDebugInfo() {
// 		return debugInfo;
// 	}
// 
// 	public SearchResultWrapper setDebugInfo(String debugInfo) {
// 		this.debugInfo = debugInfo;
// 		return this;
// 	}
// 	
// }


// Path: src/main/java/com/difference/historybook/resources/CollectionResource.java
import com.difference.historybook.index.Index;
import com.difference.historybook.index.IndexException;
import com.difference.historybook.index.SearchResultWrapper;
import java.time.Instant;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

			) throws IndexException {
		LOG.debug("Received: {} {} {}", collection, url, timestamp.toString());
		index.indexPage(collection, url, timestamp, body);
		return Response.accepted().build(); //TODO: What is the correct response code?
	}
	
	//TODO: support date range queries

	/**
	 * Execute a search against the index
	 * 
	 * @param collection the namespaced collection to search within
	 * @param query the query to pass to the index
	 * @param offsetString 0 based offset within the search results (used for paging)
	 * @param sizeString maximum number of results to return
	 * @return the search results within a metadata wrapper
	 * @see Response
	 * @throws NumberFormatException
	 * @throws IndexException
	 */
	@GET
	@Produces("application/json")
	public Response getSearchResult(
			@PathParam("collection") String collection,
			@QueryParam("q") String query,
			@QueryParam("offset") @DefaultValue("0") String offsetString,
			@QueryParam("size") @DefaultValue("10") String sizeString,
			@QueryParam("debug") @DefaultValue("false") boolean debugFlag
			) throws NumberFormatException, IndexException {
		LOG.debug("Query: {} query:{} offset:{} size:{} debug:{}", collection, query, offsetString, sizeString, debugFlag);
		SearchResultWrapper results = index.search(