diff --git a/README.md b/README.md index ddf64bae0..a31b21d59 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ mvn test The following resources introduce and document the Java API: * [The Java API in Five Minutes](http://developer.marklogic.com/try/java/index) -* [JavaDoc](http://docs.marklogic.com/guide/java) -* [User Guide](http://docs.marklogic.com/javadoc/client/index.html) +* [Java Application Developer's Guide](http://docs.marklogic.com/guide/java) +* [JavaDoc](http://docs.marklogic.com/javadoc/client/index.html) ### Installing diff --git a/pom.xml b/pom.xml index a85a08dd7..dd24ccff1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,14 +4,22 @@ com.marklogic client-api-java jar - 3.0-SNAPSHOT + 3.0.0-EA2 client-api-java http://developer.marklogic.com ${project.name} 2.0 ${maven.build.timestamp} yyyy-MM-dd UTF-8 + github + + + internal.repo + Temporary Staging Repository + file://${project.build.directory}/mvn-repo + + @@ -120,6 +128,37 @@ + + maven-deploy-plugin + 2.8.1 + + internal.repo::default::file://${project.build.directory}/mvn-repo + + + + com.github.github + site-maven-plugin + 0.9 + + Maven artifacts for ${project.version} + true + true + ${project.build.directory}/mvn-repo + refs/heads/mvn-repo + **/* + java-client-api + marklogic + + + + + + site + + deploy + + + @@ -174,10 +213,20 @@ slf4j-api 1.7.4 + + com.fasterxml.jackson.core + jackson-core + 2.4.1 + + + com.fasterxml.jackson.core + jackson-annotations + 2.4.1 + com.fasterxml.jackson.core jackson-databind - 2.2.1 + 2.4.1 @@ -229,5 +278,29 @@ 2.3 provided + + org.geonames + geonames + 1.0 + provided + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.4.1 + test + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + 2.4.1 + test + + + com.google.guava + guava + 16.0.1 + test + diff --git a/src/main/java/com/marklogic/client/DatabaseClient.java b/src/main/java/com/marklogic/client/DatabaseClient.java index 1b2d51066..7d8551f7f 100644 --- a/src/main/java/com/marklogic/client/DatabaseClient.java +++ b/src/main/java/com/marklogic/client/DatabaseClient.java @@ -16,6 +16,7 @@ package com.marklogic.client; import java.io.OutputStream; +import java.io.Serializable; import com.marklogic.client.admin.ServerConfigurationManager; import com.marklogic.client.document.BinaryDocumentManager; @@ -28,6 +29,7 @@ import com.marklogic.client.query.QueryManager; import com.marklogic.client.alerting.RuleManager; import com.marklogic.client.util.RequestLogger; +import com.marklogic.client.pojo.PojoRepository; /** * A Database Client instantiates document and query managers and other objects @@ -110,6 +112,19 @@ public interface DatabaseClient { */ public ServerConfigurationManager newServerConfigManager(); + /** + * Creates a PojoRepository specific to the specified class and its id type. + * The PojoRepository provides a facade for persisting, retrieving, and + * querying data contained in Java objects. Annotations are required to + * identify the id field and any fields for which you wish to create indexes. + * + * @param clazz the class type for this PojoRepository to handle + * @param idClass the class type of the id field for this clazz, must obviously + * be Serializable or we'll struggle to marshall it + * @return the initialized PojoRepository + **/ + public PojoRepository newPojoRepository(Class clazz, Class idClass); + /** * Initializes a manager for a extension resource. * diff --git a/src/main/java/com/marklogic/client/Page.java b/src/main/java/com/marklogic/client/Page.java index 5b4a485d8..1ca918ec8 100644 --- a/src/main/java/com/marklogic/client/Page.java +++ b/src/main/java/com/marklogic/client/Page.java @@ -17,17 +17,66 @@ import java.util.Iterator; +/** A generic interface for pagination through large sets of items of type <T>. */ public interface Page extends Iterable { + /** An iterator over the items in this page. */ public Iterator iterator(); + + /** The start position of this page within all possible items. For result sets + * this is the position of the first result within the result set. + * @return the start position + */ public long getStart(); + + /** The page size which is the maximum number of items allowed in one page. + * @return the page size */ public long getPageSize(); + + /** The total count (potentially an estimate) of all possible items in the set. + * For result sets this is the number of items within the result set. + * For search result sets this is the estimated number of matching items. + * @return the total count of possible items */ public long getTotalSize(); + + /** The count of items in this page, which is always less than getPageSize(). + * If ({@link #getTotalSize()} - {@link #getStart()}) > {@link #getPageSize()} + * then size() == getPageSize(). + * @return the count of items in this page + */ public long size(); + + + /** The number of pages covering all possible items. + * @return the number of pages. Literally, + *
{@code (long) Math.ceil((double) getTotalSize() / (double) getPageSize()); }
+ */ public long getTotalPages(); + + /** Whether there are any items in this page. + * @return true if {@code size() > 0; } + */ public boolean hasContent(); + + /** Whether there are any items in the next page. + * @return true if {@code getPageNumber() < getTotalPages(); } + */ public boolean hasNextPage(); + + /** Whether there is a previous page. + * @return true if {@code getPageNumber() > 0 } + */ public boolean hasPreviousPage(); + + /** The page number within the count of all possible pages. + * @return {@code (long) Math.floor((double) start / (double) getPageSize()) + 1; } + */ public long getPageNumber(); + + /** @return true if {@code getPageNumber() == 1 } + */ public boolean isFirstPage(); + + /** @return true if {@code getPageNumber() == getTotalPages() } + */ public boolean isLastPage(); } diff --git a/src/main/java/com/marklogic/client/admin/config/QueryOptions.java b/src/main/java/com/marklogic/client/admin/config/QueryOptions.java index b7b8d9451..71b13823d 100644 --- a/src/main/java/com/marklogic/client/admin/config/QueryOptions.java +++ b/src/main/java/com/marklogic/client/admin/config/QueryOptions.java @@ -49,15 +49,17 @@ * {@link com.marklogic.client.io.marker.StructureReadHandle read handle} * implementation instead of this class to write or read * query options. For instance: - *
String opts = new StringBuilder()
- *     .append("<options xmlns=\"http://marklogic.com/appservices/search\">")
- *     .append(    "<debug>true</debug>")
- *     .append("</options>")
- *     .toString();
- *optsMgr.writeOptions("debug", new StringHandle(opts));
+ *
{@code
+ *  String opts = new StringBuilder()
+ *      .append("")
+ *      .append(    "true")
+ *      .append("")
+ *      .toString();
+ *  optsMgr.writeOptions("debug", new StringHandle(opts)); }
* or - *
String opts = "{\"options\":{\"debug\":true}}";
- *optsMgr.writeOptions("debug", new StringHandle(opts).withFormat(Format.JSON));
+ *
{@code
+ *  String opts = "{\"options\":{\"debug\":true}}";
+ *  optsMgr.writeOptions("debug", new StringHandle(opts).withFormat(Format.JSON)); }
*/ @Deprecated @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/com/marklogic/client/admin/config/QueryOptionsBuilder.java b/src/main/java/com/marklogic/client/admin/config/QueryOptionsBuilder.java index b9a77b45c..8e4f91656 100644 --- a/src/main/java/com/marklogic/client/admin/config/QueryOptionsBuilder.java +++ b/src/main/java/com/marklogic/client/admin/config/QueryOptionsBuilder.java @@ -94,15 +94,17 @@ * {@link com.marklogic.client.io.marker.StructureReadHandle read handle} * implementation instead of this class to write or read * query options. For instance: - *
String opts = new StringBuilder()
- *     .append("<options xmlns=\"http://marklogic.com/appservices/search\">")
- *     .append(    "<debug>true</debug>")
- *     .append("</options>")
- *     .toString();
- *optsMgr.writeOptions("debug", new StringHandle(opts));
+ *
{@code
+ *  String opts = new StringBuilder()
+ *       .append("")
+ *       .append(    "true")
+ *       .append("")
+ *       .toString();
+ *  optsMgr.writeOptions("debug", new StringHandle(opts)); }
* or - *
String opts = "{\"options\":{\"debug\":true}}";
- *optsMgr.writeOptions("debug", new StringHandle(opts).withFormat(Format.JSON));
+ *
{@code
+ *  String opts = "{\"options\":{\"debug\":true}}";
+ *  optsMgr.writeOptions("debug", new StringHandle(opts).withFormat(Format.JSON)); }
*/ @Deprecated public class QueryOptionsBuilder { diff --git a/src/main/java/com/marklogic/client/document/DocumentManager.java b/src/main/java/com/marklogic/client/document/DocumentManager.java index 0c46b755e..a7b2fe2c3 100644 --- a/src/main/java/com/marklogic/client/document/DocumentManager.java +++ b/src/main/java/com/marklogic/client/document/DocumentManager.java @@ -30,6 +30,7 @@ import com.marklogic.client.io.marker.DocumentPatchHandle; import com.marklogic.client.io.marker.SearchReadHandle; import com.marklogic.client.query.QueryDefinition; +import com.marklogic.client.query.QueryManager.QueryView; /** * A Document Manager provides database operations on a document. @@ -367,14 +368,58 @@ public T read(DocumentDescriptor desc, DocumentMetadataReadHandle public T read(DocumentDescriptor desc, DocumentMetadataReadHandle metadataHandle, T contentHandle, ServerTransform transform, Transaction transaction) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException; + /** + * Reads from the database a list of documents matching the provided uris. Allows + * iteration across matching documents and metadata (only if setMetadataCategories + * has been called to request metadata). To find out how many of your uris matched, + * call the {@link DocumentPage#size() DocumentPage.size()} method. + * + * @param uris the database uris identifying documents to retrieve + * @return the DocumentPage of matching documents and metadata + */ public DocumentPage read(String... uris); + /** + * Reads from the database a list of documents matching the provided uris. Allows + * iteration across matching documents and metadata (only if setMetadataCategories + * has been called to request metadata). To find out how many of your uris matched, + * call the {@link DocumentPage#size() DocumentPage.size()} method. + * + * @param transform the transform to be run on the server on each document (must already be installed) + * @param uris the database uris identifying documents to retrieve + * @return the DocumentPage of matching documents and metadata + */ public DocumentPage read(ServerTransform transform, String... uris); + /** + * Reads from the database a list of documents matching the provided uris. Allows + * iteration across matching documents and metadata (only if setMetadataCategories + * has been called to request metadata). To find out how many of your uris matched, + * call the {@link DocumentPage#size() DocumentPage.size()} method. + * + * @param transaction the transaction in which this read is participating + * @param uris the database uris identifying documents to retrieve + * @return the DocumentPage of matching documents and metadata + */ public DocumentPage read(Transaction transaction, String... uris); + /** + * Reads from the database a list of documents matching the provided uris. Allows + * iteration across matching documents and metadata (only if setMetadataCategories + * has been called to request metadata). To find out how many of your uris matched, + * call the {@link DocumentPage#size() DocumentPage.size()} method. + * + * @param transform the transform to be run on the server on each document (must already be installed) + * @param transaction the transaction in which this read is participating + * @param uris the database uris identifying documents to retrieve + * @return the DocumentPage of matching documents and metadata + */ public DocumentPage read(ServerTransform transform, Transaction transaction, String... uris); + public DocumentPage readMetadata(String... uris); + + public DocumentPage readMetadata(Transaction transaction, String... uris); + public DocumentPage search(QueryDefinition querydef, long start); public DocumentPage search(QueryDefinition querydef, long start, Transaction transaction); @@ -387,6 +432,14 @@ public T read(DocumentDescriptor desc, DocumentMetadataReadHandle public void setPageLength(long length); + public Format getResponseFormat(); + + public void setResponseFormat(Format format); + + public QueryView getSearchView(); + + public void setSearchView(QueryView view); + public DocumentWriteSet newWriteSet(); public void write(DocumentWriteSet writeSet); diff --git a/src/main/java/com/marklogic/client/document/DocumentPatchBuilder.java b/src/main/java/com/marklogic/client/document/DocumentPatchBuilder.java index 0cd69138f..baa1f9c94 100644 --- a/src/main/java/com/marklogic/client/document/DocumentPatchBuilder.java +++ b/src/main/java/com/marklogic/client/document/DocumentPatchBuilder.java @@ -57,6 +57,36 @@ public String toString() { } } + + /** + * MarkLogic's REST API patch operations support two path languages for JSON, + * XPATH and JSONPATH. Default for MarkLogic 8 is XPATH, + * but you can use the backwards-compatible JSONPATH too. + */ + public enum PathLanguage { + + /** + * Indicates that the given patch uses the XPATH language. + */ + XPATH, + + /** + * Indicates that the given patch uses the JSONPATH language. + */ + JSONPATH; + + @Override + public String toString() { + return super.toString().toLowerCase(); + }; + + } + + /** + * Specifies the language for this patch to use + */ + public DocumentPatchBuilder pathLanguage(PathLanguage pathLang); + /** * Specifies an operation to delete an existing JSON or XML fragment. * @param selectPath the location of the JSON or XML fragment diff --git a/src/main/java/com/marklogic/client/document/DocumentWriteOperation.java b/src/main/java/com/marklogic/client/document/DocumentWriteOperation.java index d58c332a3..20734f00f 100644 --- a/src/main/java/com/marklogic/client/document/DocumentWriteOperation.java +++ b/src/main/java/com/marklogic/client/document/DocumentWriteOperation.java @@ -19,7 +19,7 @@ import com.marklogic.client.io.marker.DocumentMetadataWriteHandle; public interface DocumentWriteOperation { - public enum OperationType { METADATA_DEFAULT, DOCUMENT_WRITE }; + public enum OperationType { METADATA_DEFAULT, DISABLE_METADATA_DEFAULT, DOCUMENT_WRITE }; public OperationType getOperationType(); diff --git a/src/main/java/com/marklogic/client/document/DocumentWriteSet.java b/src/main/java/com/marklogic/client/document/DocumentWriteSet.java index 6c11a0e74..d83a9d53d 100644 --- a/src/main/java/com/marklogic/client/document/DocumentWriteSet.java +++ b/src/main/java/com/marklogic/client/document/DocumentWriteSet.java @@ -23,6 +23,8 @@ public interface DocumentWriteSet extends Set { public DocumentWriteSet addDefault(DocumentMetadataWriteHandle metadataHandle); + public DocumentWriteSet disableDefault(); + public DocumentWriteSet add(String docId, AbstractWriteHandle contentHandle); public DocumentWriteSet add(String docId, DocumentMetadataWriteHandle metadataHandle, AbstractWriteHandle contentHandle); diff --git a/src/main/java/com/marklogic/client/impl/BasicPage.java b/src/main/java/com/marklogic/client/impl/BasicPage.java index 6aca6c215..430f75e1f 100644 --- a/src/main/java/com/marklogic/client/impl/BasicPage.java +++ b/src/main/java/com/marklogic/client/impl/BasicPage.java @@ -25,6 +25,9 @@ public class BasicPage implements Page { private long pageSize; private long totalSize; + protected BasicPage(Class type) { + } + public BasicPage(Iterable iterable, long start, long pageSize, long totalSize) { this.iterable = iterable; this.start = start; diff --git a/src/main/java/com/marklogic/client/impl/BinaryDocumentImpl.java b/src/main/java/com/marklogic/client/impl/BinaryDocumentImpl.java index b52f8f009..fce15e3d0 100644 --- a/src/main/java/com/marklogic/client/impl/BinaryDocumentImpl.java +++ b/src/main/java/com/marklogic/client/impl/BinaryDocumentImpl.java @@ -132,7 +132,7 @@ public T read(DocumentDescriptor desc, DocumentMeta RequestParameters extraParams = new RequestParameters(); if (length > 0) - extraParams.put("range", "bytes="+start+"-"+(start + length)); + extraParams.put("range", "bytes="+start+"-"+(start + length - 1)); else extraParams.put("range", "bytes="+String.valueOf(start)); diff --git a/src/main/java/com/marklogic/client/impl/DatabaseClientImpl.java b/src/main/java/com/marklogic/client/impl/DatabaseClientImpl.java index 0b47e7f38..cea7ec161 100644 --- a/src/main/java/com/marklogic/client/impl/DatabaseClientImpl.java +++ b/src/main/java/com/marklogic/client/impl/DatabaseClientImpl.java @@ -16,6 +16,7 @@ package com.marklogic.client.impl; import java.io.OutputStream; +import java.io.Serializable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,6 +37,8 @@ import com.marklogic.client.document.TextDocumentManager; import com.marklogic.client.Transaction; import com.marklogic.client.document.XMLDocumentManager; +import com.marklogic.client.pojo.PojoRepository; +import com.marklogic.client.impl.PojoRepositoryImpl; public class DatabaseClientImpl implements DatabaseClient { static final private Logger logger = LoggerFactory.getLogger(DatabaseClientImpl.class); @@ -120,6 +123,11 @@ public ServerConfigurationManager newServerConfigManager() { configMgr.setHandleRegistry(getHandleRegistry()); return configMgr; } + @Override + public PojoRepository newPojoRepository(Class clazz, Class idClass) { + return new PojoRepositoryImpl(this, clazz, idClass); + + } @Override public RequestLogger newLogger(OutputStream out) { diff --git a/src/main/java/com/marklogic/client/impl/DocumentManagerImpl.java b/src/main/java/com/marklogic/client/impl/DocumentManagerImpl.java index 5950531ed..85afb88cc 100644 --- a/src/main/java/com/marklogic/client/impl/DocumentManagerImpl.java +++ b/src/main/java/com/marklogic/client/impl/DocumentManagerImpl.java @@ -16,6 +16,7 @@ package com.marklogic.client.impl; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -23,7 +24,6 @@ import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; - import com.marklogic.client.DatabaseClientFactory.HandleFactoryRegistry; import com.marklogic.client.FailedRequestException; import com.marklogic.client.ForbiddenUserException; @@ -67,6 +67,10 @@ public boolean add(Metadata e) { isProcessedMetadataModified = true; return super.add(e); } + public boolean addAll(Collection c) { + isProcessedMetadataModified = true; + return super.addAll(c); + } }; { processedMetadata.add(Metadata.ALL); @@ -322,6 +326,13 @@ public DocumentPage read(ServerTransform transform, String... uris) { } public DocumentPage read(ServerTransform transform, Transaction transaction, String... uris) { + boolean withContent = true; + return read(transform, transaction, withContent, uris); + } + + public DocumentPage read(ServerTransform transform, Transaction transaction, + boolean withContent, String... uris) + { if (uris == null || uris.length == 0) throw new IllegalArgumentException("Attempt to call read with no uris"); @@ -334,10 +345,24 @@ public DocumentPage read(ServerTransform transform, Transaction transaction, Str // the default for bulk is no metadata, which differs from the normal default of ALL isProcessedMetadataModified ? processedMetadata : null, responseFormat, - null, + mergeTransformParameters( + (transform != null) ? transform : getReadTransform(), + null + ), + withContent, uris); } + public DocumentPage readMetadata(String... uris) { + boolean withContent = false; + return read(null, null, withContent, uris); + } + + public DocumentPage readMetadata(Transaction transaction, String... uris) { + boolean withContent = false; + return read(null, transaction, withContent, uris); + } + public DocumentPage search(QueryDefinition querydef, long start) { return search(querydef, start, null, null); } diff --git a/src/main/java/com/marklogic/client/impl/DocumentMetadataPatchBuilderImpl.java b/src/main/java/com/marklogic/client/impl/DocumentMetadataPatchBuilderImpl.java index 3186bf117..ed5fd8da1 100644 --- a/src/main/java/com/marklogic/client/impl/DocumentMetadataPatchBuilderImpl.java +++ b/src/main/java/com/marklogic/client/impl/DocumentMetadataPatchBuilderImpl.java @@ -33,6 +33,7 @@ import com.marklogic.client.MarkLogicIOException; import com.marklogic.client.document.DocumentManager.Metadata; import com.marklogic.client.document.DocumentMetadataPatchBuilder; +import com.marklogic.client.document.DocumentPatchBuilder.PathLanguage; import com.marklogic.client.io.DocumentMetadataHandle.Capability; import com.marklogic.client.io.Format; import com.marklogic.client.io.StringHandle; @@ -53,6 +54,7 @@ class DocumentMetadataPatchBuilderImpl reserved.put("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI); }; + static class XMLOutputSerializer { private StringWriter writer; private XMLStreamWriter serializer; @@ -340,7 +342,9 @@ static class AddCollectionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { - writeStartInsert(serializer, "$.collections", "last-child", null); + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.collections" : "/node()/array-node('collections')"; + writeStartInsert(serializer, pathString, "last-child", null); serializer.writeStartEntry("content"); serializer.writeStringValue(collection); serializer.writeEndObject(); @@ -364,7 +368,10 @@ static class DeleteCollectionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { - writeDelete(serializer, "$.collections[*][?(@="+JSONStringWriter.toJSON(collection)+")]", null); + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.collections[*][?(@="+JSONStringWriter.toJSON(collection)+")]" : + "/node()/array-node('collections')/node()[.="+JSONStringWriter.toJSON(collection)+"]"; + writeDelete(serializer, pathString, null); } @Override public void write(XMLOutputSerializer out) throws Exception { @@ -386,8 +393,12 @@ static class ReplaceCollectionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.collections[*][?(@="+JSONStringWriter.toJSON(oldCollection)+")]" : + "/node()/array-node('collections')/node()[.="+JSONStringWriter.toJSON(oldCollection)+"]"; + writeStartReplace(serializer, - "$.collections[*][?(@="+JSONStringWriter.toJSON(oldCollection)+")]", + pathString, null ); serializer.writeStartEntry("content"); @@ -419,7 +430,10 @@ static class AddPermissionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { - writeStartInsert(serializer, "$.permissions", "last-child", null); + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.permissions" : + "/node()/array-node('permissions')"; + writeStartInsert(serializer, pathString, "last-child", null); serializer.writeStartEntry("content"); serializer.writeStartObject(); serializer.writeStartEntry("role-name"); @@ -463,8 +477,13 @@ static class DeletePermissionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { + + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.permissions.[*][?(@.role-name="+JSONStringWriter.toJSON(role)+")]": + "/node()/array-node('permissions')/object-node()[role-name = "+JSONStringWriter.toJSON(role)+"]"; + writeDelete(serializer, - "$.permissions.[*][?(@.role-name="+JSONStringWriter.toJSON(role)+")]", + pathString, null ); } @@ -488,8 +507,12 @@ static class ReplacePermissionOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.permissions.[*][?(@.role-name="+JSONStringWriter.toJSON(oldRole)+")]": + "/node()/array-node('permissions')/object-node()[role-name = "+JSONStringWriter.toJSON(oldRole)+"]"; + writeStartReplace(serializer, - "$.permissions.[*][?(@.role-name="+JSONStringWriter.toJSON(oldRole)+")]", + pathString, null ); serializer.writeStartEntry("content"); @@ -550,7 +573,11 @@ static class AddPropertyOperation extends PatchOperation { @Override public void write(JSONStringWriter serializer) { // TODO: error if name empty - writeStartInsert(serializer, "$.properties", "last-child", null); + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.properties" : + "/node()/node('properties')"; + + writeStartInsert(serializer, pathString, "last-child", null); serializer.writeStartEntry("content"); serializer.writeStartObject(); serializer.writeStartEntry(name); @@ -590,8 +617,12 @@ static class DeletePropertyOperation extends PatchOperation { @Override public void write(JSONStringWriter serializer) { // TODO: error if name empty + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.properties.["+JSONStringWriter.toJSON(name)+"]": + "/node()/node('properties')/node()[name(.)="+JSONStringWriter.toJSON(name)+"]"; + writeDelete(serializer, - "$.properties.["+JSONStringWriter.toJSON(name)+"]", + pathString, null ); } @@ -627,8 +658,11 @@ static class ReplacePropertyOperation extends PatchOperation { @Override public void write(JSONStringWriter serializer) { // TODO: error if name empty + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.properties.["+JSONStringWriter.toJSON(oldName)+"]": + "/node()/node('properties')/node()[name(.)="+JSONStringWriter.toJSON(oldName)+"]"; writeStartReplace(serializer, - "$.properties.["+JSONStringWriter.toJSON(oldName)+"]", + pathString, null ); serializer.writeStartEntry("content"); @@ -674,8 +708,11 @@ static class ReplacePropertyApplyOperation extends PatchOperation { @Override public void write(JSONStringWriter serializer) { // TODO: error if name empty + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.properties.["+JSONStringWriter.toJSON(name)+"]": + "/node()/node('properties')/node()[name(.)="+JSONStringWriter.toJSON(name)+"]"; writeReplaceApply(serializer, - "$.properties.["+JSONStringWriter.toJSON(name)+"]", + pathString, null, call ); @@ -699,7 +736,11 @@ static class SetQualityOperation extends PatchOperation { } @Override public void write(JSONStringWriter serializer) { - writeStartReplace(serializer, "$.quality", null); + String pathString = serializer.getPathLanguage() == PathLanguage.JSONPATH ? + "$.quality": + "/node()/node('quality')"; + + writeStartReplace(serializer, pathString, null); serializer.writeStartEntry("content"); serializer.writeNumberValue(quality); serializer.writeEndObject(); @@ -742,6 +783,7 @@ public boolean isOnContent() { protected Format format; protected Set processedMetadata; protected boolean onContent = false; + protected PathLanguage pathLang = PathLanguage.XPATH; DocumentMetadataPatchBuilderImpl(Format format) { super(); @@ -978,9 +1020,11 @@ public PatchHandle build() throws MarkLogicIOException { if (format == Format.JSON) { handle.setFormat(format); - JSONStringWriter writer = new JSONStringWriter(); + JSONStringWriter writer = new JSONStringWriter(this.pathLang); writer.writeStartObject(); + writer.writeStartEntry("pathlang"); + writer.writeStringValue(pathLang.toString()); writer.writeStartEntry("patch"); writer.writeStartArray(); diff --git a/src/main/java/com/marklogic/client/impl/DocumentPatchBuilderImpl.java b/src/main/java/com/marklogic/client/impl/DocumentPatchBuilderImpl.java index 5a784232c..74fa626d9 100644 --- a/src/main/java/com/marklogic/client/impl/DocumentPatchBuilderImpl.java +++ b/src/main/java/com/marklogic/client/impl/DocumentPatchBuilderImpl.java @@ -278,4 +278,10 @@ private void onContent() { onContent = true; } } + + @Override + public DocumentPatchBuilder pathLanguage(PathLanguage pathLang) { + this.pathLang = pathLang; + return this; + } } diff --git a/src/main/java/com/marklogic/client/impl/DocumentWriteSetImpl.java b/src/main/java/com/marklogic/client/impl/DocumentWriteSetImpl.java index 53ce9f831..414fc7be9 100644 --- a/src/main/java/com/marklogic/client/impl/DocumentWriteSetImpl.java +++ b/src/main/java/com/marklogic/client/impl/DocumentWriteSetImpl.java @@ -20,6 +20,8 @@ import com.marklogic.client.document.DocumentWriteOperation; import com.marklogic.client.document.DocumentWriteOperation.OperationType; import com.marklogic.client.impl.DocumentWriteOperationImpl; +import com.marklogic.client.io.Format; +import com.marklogic.client.io.StringHandle; import com.marklogic.client.io.marker.AbstractWriteHandle; import com.marklogic.client.io.marker.DocumentMetadataWriteHandle; @@ -32,26 +34,32 @@ public DocumentWriteSet addDefault(DocumentMetadataWriteHandle metadataHandle) { return this; } + public DocumentWriteSet disableDefault() { + add(new DocumentWriteOperationImpl(OperationType.DISABLE_METADATA_DEFAULT, + null, new StringHandle("{ }").withFormat(Format.JSON), null)); + return this; + } + public DocumentWriteSet add(String docId, AbstractWriteHandle contentHandle) { - add(new DocumentWriteOperationImpl(OperationType.METADATA_DEFAULT, + add(new DocumentWriteOperationImpl(OperationType.DOCUMENT_WRITE, docId, null, contentHandle)); return this; } public DocumentWriteSet add(String docId, DocumentMetadataWriteHandle metadataHandle, AbstractWriteHandle contentHandle) { - add(new DocumentWriteOperationImpl(OperationType.METADATA_DEFAULT, + add(new DocumentWriteOperationImpl(OperationType.DOCUMENT_WRITE, docId, metadataHandle, contentHandle)); return this; } public DocumentWriteSet add(DocumentDescriptor desc, AbstractWriteHandle contentHandle) { - add(new DocumentWriteOperationImpl(OperationType.METADATA_DEFAULT, + add(new DocumentWriteOperationImpl(OperationType.DOCUMENT_WRITE, desc.getUri(), null, contentHandle)); return this; } public DocumentWriteSet add(DocumentDescriptor desc, DocumentMetadataWriteHandle metadataHandle, AbstractWriteHandle contentHandle) { - add(new DocumentWriteOperationImpl(OperationType.METADATA_DEFAULT, + add(new DocumentWriteOperationImpl(OperationType.DOCUMENT_WRITE, desc.getUri(), metadataHandle, contentHandle)); return this; } diff --git a/src/main/java/com/marklogic/client/impl/ExtensionLibrariesManagerImpl.java b/src/main/java/com/marklogic/client/impl/ExtensionLibrariesManagerImpl.java index 8ef0a2c55..a3e2561a4 100644 --- a/src/main/java/com/marklogic/client/impl/ExtensionLibrariesManagerImpl.java +++ b/src/main/java/com/marklogic/client/impl/ExtensionLibrariesManagerImpl.java @@ -44,7 +44,7 @@ void setHandleRegistry(HandleFactoryRegistry handleRegistry) { @Override public ExtensionLibraryDescriptor[] list() throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException { - return list("/ext/"); + return list("/ext"); } @Override public ExtensionLibraryDescriptor[] list(String directory) diff --git a/src/main/java/com/marklogic/client/impl/HandleFactoryRegistryImpl.java b/src/main/java/com/marklogic/client/impl/HandleFactoryRegistryImpl.java index 910d0f1a0..94ab84bd5 100644 --- a/src/main/java/com/marklogic/client/impl/HandleFactoryRegistryImpl.java +++ b/src/main/java/com/marklogic/client/impl/HandleFactoryRegistryImpl.java @@ -25,6 +25,8 @@ import com.marklogic.client.io.FileHandle; import com.marklogic.client.io.InputSourceHandle; import com.marklogic.client.io.InputStreamHandle; +import com.marklogic.client.io.JacksonHandle; +import com.marklogic.client.io.JacksonParserHandle; import com.marklogic.client.io.ReaderHandle; import com.marklogic.client.io.SourceHandle; import com.marklogic.client.io.StringHandle; @@ -46,6 +48,8 @@ public static HandleFactoryRegistry registerDefaults(HandleFactoryRegistry regis registry.register(FileHandle.newFactory()); registry.register(InputSourceHandle.newFactory()); registry.register(InputStreamHandle.newFactory()); + registry.register(JacksonHandle.newFactory()); + registry.register(JacksonParserHandle.newFactory()); registry.register(ReaderHandle.newFactory()); registry.register(SourceHandle.newFactory()); registry.register(StringHandle.newFactory()); @@ -141,4 +145,4 @@ Class getRegisteredType(Class type) { return null; } -} \ No newline at end of file +} diff --git a/src/main/java/com/marklogic/client/impl/JSONDocumentImpl.java b/src/main/java/com/marklogic/client/impl/JSONDocumentImpl.java index f30f8e61c..0754f5a86 100644 --- a/src/main/java/com/marklogic/client/impl/JSONDocumentImpl.java +++ b/src/main/java/com/marklogic/client/impl/JSONDocumentImpl.java @@ -30,6 +30,7 @@ public class JSONDocumentImpl JSONDocumentImpl(RESTServices services) { super(services,Format.JSON); + setResponseFormat(Format.JSON); } @Override diff --git a/src/main/java/com/marklogic/client/impl/JSONStringWriter.java b/src/main/java/com/marklogic/client/impl/JSONStringWriter.java index f8897e05a..26d1bff0f 100644 --- a/src/main/java/com/marklogic/client/impl/JSONStringWriter.java +++ b/src/main/java/com/marklogic/client/impl/JSONStringWriter.java @@ -17,14 +17,22 @@ import java.io.CharArrayWriter; +import com.marklogic.client.document.DocumentPatchBuilder.PathLanguage; + public class JSONStringWriter { private StringBuilder builder; private boolean isFirst = false; + private PathLanguage pathLang; - JSONStringWriter() { + JSONStringWriter(PathLanguage pathLang) { super(); + this.pathLang = pathLang; builder = new StringBuilder(); } + + public PathLanguage getPathLanguage() { + return this.pathLang; + } public void writeStartObject() { builder.append("{"); diff --git a/src/main/java/com/marklogic/client/impl/JacksonBaseHandle.java b/src/main/java/com/marklogic/client/impl/JacksonBaseHandle.java new file mode 100644 index 000000000..0f0fc50f9 --- /dev/null +++ b/src/main/java/com/marklogic/client/impl/JacksonBaseHandle.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.marklogic.client.MarkLogicIOException; +import com.marklogic.client.io.BaseHandle; +import com.marklogic.client.io.Format; +import com.marklogic.client.io.OutputStreamSender; +import com.marklogic.client.io.marker.BufferableHandle; +import com.marklogic.client.io.marker.JSONReadHandle; +import com.marklogic.client.io.marker.JSONWriteHandle; +import com.marklogic.client.io.marker.StructureReadHandle; +import com.marklogic.client.io.marker.StructureWriteHandle; +import com.marklogic.client.io.marker.TextReadHandle; +import com.marklogic.client.io.marker.TextWriteHandle; +import com.marklogic.client.io.marker.XMLReadHandle; +import com.marklogic.client.io.marker.XMLWriteHandle; + +public abstract class JacksonBaseHandle + extends BaseHandle + implements OutputStreamSender, BufferableHandle, JSONReadHandle, JSONWriteHandle, + TextReadHandle, TextWriteHandle, + XMLReadHandle, XMLWriteHandle, + StructureReadHandle, StructureWriteHandle +{ + private ObjectMapper mapper; + + protected JacksonBaseHandle() { + super(); + super.setFormat(Format.JSON); + } + + /** + * Returns the mapper used to construct node objects from JSON. + * @return the JSON mapper. + */ + public ObjectMapper getMapper() { + if (mapper == null) { + mapper = new ObjectMapper(); + mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); + } + return mapper; + } + + /** + * Enables clients to use any mapper, including databinding mappers for formats other than JSON. + * Use at your own risk! Note that you may want to configure your mapper as we do to not close + * streams which we may need to reuse if we have to resend a network request: + * + * mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + * mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); + * + **/ + public void setMapper(ObjectMapper mapper) { + this.mapper = mapper; + } + + public abstract void set(T content); + @Override + public void fromBuffer(byte[] buffer) { + if (buffer == null || buffer.length == 0) + set(null); + else + receiveContent(new ByteArrayInputStream(buffer)); + } + @Override + public byte[] toBuffer() { + try { + if ( ! hasContent() ) + return null; + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + write(buffer); + + return buffer.toByteArray(); + } catch (IOException e) { + throw new MarkLogicIOException(e); + } + } + + /** + * Returns the JSON as a string. + */ + @Override + public String toString() { + try { + return new String(toBuffer(),"UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new MarkLogicIOException(e); + } + } + + @Override + protected Class receiveAs() { + return InputStream.class; + } + @Override + protected OutputStreamSender sendContent() { + if ( ! hasContent() ) { + throw new IllegalStateException("No document to write"); + } + return this; + } + + protected abstract boolean hasContent(); + + @Override + public abstract void write(OutputStream out) throws IOException; +} + diff --git a/src/main/java/com/marklogic/client/impl/JerseyServices.java b/src/main/java/com/marklogic/client/impl/JerseyServices.java index 841056aff..bb6431e40 100644 --- a/src/main/java/com/marklogic/client/impl/JerseyServices.java +++ b/src/main/java/com/marklogic/client/impl/JerseyServices.java @@ -694,12 +694,12 @@ private boolean getDocumentImpl(RequestLogger reqlog, @Override public DocumentPage getBulkDocuments(RequestLogger reqlog, String transactionId, Set categories, - Format format, RequestParameters extraParams, String... uris) + Format format, RequestParameters extraParams, boolean withContent, String... uris) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException { boolean hasMetadata = categories != null && categories.size() > 0; JerseyResultIterator iterator = - getBulkDocumentsImpl(reqlog, transactionId, categories, format, extraParams, uris); - return convertToDocumentPage(iterator, hasMetadata); + getBulkDocumentsImpl(reqlog, transactionId, categories, format, extraParams, withContent, uris); + return convertToDocumentPage(iterator, withContent, hasMetadata); } @Override @@ -708,16 +708,19 @@ public DocumentPage getBulkDocuments(RequestLogger reqlog, long start, long pageLength, String transactionId, SearchReadHandle searchHandle, QueryView view, - Set categories, Format format, RequestParameters extraParams) + Set categories, Format format, RequestParameters extraParams) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException { boolean hasMetadata = categories != null && categories.size() > 0; + boolean hasContent = true; JerseyResultIterator iterator = getBulkDocumentsImpl(reqlog, querydef, start, pageLength, transactionId, searchHandle, view, categories, format, extraParams); - return convertToDocumentPage(iterator, hasMetadata); + return convertToDocumentPage(iterator, hasContent, hasMetadata); } - private DocumentPage convertToDocumentPage(JerseyResultIterator iterator, boolean hasMetadata) { + private DocumentPage convertToDocumentPage(JerseyResultIterator iterator, boolean hasContent, + boolean hasMetadata) + { ArrayList records = new ArrayList(); if ( iterator == null ) { return new DocumentPageImpl(records, 1, 0, 0, 0); @@ -725,17 +728,18 @@ private DocumentPage convertToDocumentPage(JerseyResultIterator iterator, boolea while (iterator.hasNext()) { JerseyResult result = iterator.next(); DocumentRecord record; - if ( hasMetadata ) { - if ( iterator.hasNext() ) { - throw new MarkLogicInternalException( - "Metadata and content parts should always come in pairs!"); - } + if ( hasContent && hasMetadata ) { JerseyResult metadata = result; JerseyResult content = iterator.next(); record = new JerseyDocumentRecord(content, metadata); - } else { + } else if ( hasContent ) { JerseyResult content = result; record = new JerseyDocumentRecord(content); + } else if ( hasMetadata ) { + JerseyResult metadata = result; + record = new JerseyDocumentRecord(null, metadata); + } else { + throw new IllegalStateException("Should never have neither content nor metadata"); } records.add(record); } @@ -745,11 +749,14 @@ record = new JerseyDocumentRecord(content); private JerseyResultIterator getBulkDocumentsImpl(RequestLogger reqlog, String transactionId, Set categories, - Format format, RequestParameters extraParams, String... uris) + Format format, RequestParameters extraParams, boolean withContent, String... uris) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException { String path = "documents"; RequestParameters params = new RequestParameters(); + if ( extraParams != null ) params.putAll(extraParams); + if (transactionId != null) params.add("txid", transactionId); + addCategoryParams(categories, params, withContent); if (format != null) params.add("format", format.toString().toLowerCase()); for (String uri: uris) { params.add("uri", uri); @@ -764,6 +771,9 @@ private JerseyResultIterator getBulkDocumentsImpl(RequestLogger reqlog, Set categories, Format format, RequestParameters extraParams) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException { MultivaluedMap params = new MultivaluedMapImpl(); + if ( extraParams != null ) params.putAll(extraParams); + boolean withContent = true; + addCategoryParams(categories, params, withContent); if (searchHandle != null && view != null) params.add("view", view.toString().toLowerCase()); if (start > 1) params.add("start", Long.toString(start)); if (pageLength > 0) params.add("pageLength", Long.toString(pageLength)); @@ -1605,6 +1615,39 @@ private void completeTransaction(String transactionId, String result) response.close(); } + private void addCategoryParams(Set categories, MultivaluedMap params, + boolean withContent) + { + if (withContent && categories == null || categories.size() == 0) { + params.add("category", "content"); + } else { + if (withContent) params.add("category", "content"); + if (categories.contains(Metadata.ALL)) { + params.add("category", "metadata"); + } else { + for (Metadata category : categories) { + params.add("category", category.name().toLowerCase()); + } + } + } + } + private void addCategoryParams(Set categories, RequestParameters params, + boolean withContent) + { + if (withContent && categories == null || categories.size() == 0) { + params.add("category", "content"); + } else { + if (withContent) params.add("category", "content"); + if (categories.contains(Metadata.ALL)) { + params.add("category", "metadata"); + } else { + for (Metadata category : categories) { + params.add("category", category.name().toLowerCase()); + } + } + } + } + private MultivaluedMap makeDocumentParams(String uri, Set categories, String transactionId, RequestParameters extraParams) { @@ -1936,12 +1979,16 @@ void init() { else if (payloadFormat != Format.XML && payloadFormat != Format.JSON) throw new IllegalArgumentException( "Cannot perform raw search for "+payloadFormat.name()); + // Fix bug https://github.com/marklogic/java-client-api/issues/29 + // by not specifying format parameter when payloadFormat differs + // may remove when https://bugtrack.marklogic.com/27638 is resolved + else if (payloadFormat == Format.JSON && "xml".equals(params.getFirst("format"))) + params.remove("format"); String payloadMimetype = baseHandle.getMimetype(); if (payloadFormat != null) { if (payloadMimetype == null) payloadMimetype = payloadFormat.getDefaultMimetype(); - params.add("format", payloadFormat.toString().toLowerCase()); } else if (payloadMimetype == null) { payloadMimetype = "application/xml"; } @@ -3390,7 +3437,15 @@ public R postBulkDocuments( HandleAccessor.checkHandle(write.getMetadata(), "write"); HandleImplementation content = HandleAccessor.checkHandle(write.getContent(), "write"); - if ( metadata != null ) { + if ( write.getOperationType() == + DocumentWriteOperation.OperationType.DISABLE_METADATA_DEFAULT ) + { + MultivaluedMap headers = new MultivaluedMapImpl(); + headers.add(HttpHeaders.CONTENT_TYPE, metadata.getMimetype()); + headers.add("Content-Disposition", "inline; category=metadata"); + headerList.add(headers); + writeHandles.add(write.getMetadata()); + } else if ( metadata != null ) { MultivaluedMap headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, metadata.getMimetype()); if ( write.getOperationType() == DocumentWriteOperation.OperationType.METADATA_DEFAULT ) { @@ -3424,7 +3479,10 @@ public R postBulkDocuments( writeHandles.add(write.getContent()); } } - RequestParameters params = transform != null ? transform : new RequestParameters(); + RequestParameters params = new RequestParameters(); + if (transform != null) { + transform.merge(params); + } if ( transactionId != null ) params.add("txid", transactionId); return postResource( reqlog, @@ -4233,6 +4291,7 @@ public JerseyResultIterator(RequestLogger reqlog, super(); this.clazz = clazz; if (partList != null && partList.size() > 0) { + this.size = partList.size(); this.reqlog = reqlog; this.partQueue = new ConcurrentLinkedQueue( partList).iterator(); @@ -4351,7 +4410,13 @@ public JerseyDocumentRecord(JerseyResult content) { } public String getUri() { - return content.getUri(); + if ( content == null && metadata != null ) { + return metadata.getUri(); + } else if ( content != null ) { + return content.getUri(); + } else { + throw new IllegalStateException("Missing both content and metadata!"); + } } public Format getFormat() { diff --git a/src/main/java/com/marklogic/client/impl/PojoPageImpl.java b/src/main/java/com/marklogic/client/impl/PojoPageImpl.java new file mode 100644 index 000000000..43bf0e2a3 --- /dev/null +++ b/src/main/java/com/marklogic/client/impl/PojoPageImpl.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.impl; + +import java.util.Iterator; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.marklogic.client.Page; +import com.marklogic.client.impl.BasicPage; +import com.marklogic.client.io.JacksonDatabindHandle; +import com.marklogic.client.document.DocumentPage; +import com.marklogic.client.pojo.PojoPage; + +public class PojoPageImpl extends BasicPage implements PojoPage, Iterator { + private Class entityClass; + private DocumentPage docPage; + + public PojoPageImpl(DocumentPage docPage, Class entityClass) { + super(entityClass); + setStart( docPage.getStart() ); + setSize( docPage.size() ); + setPageSize( docPage.getPageSize() ); + setTotalSize( docPage.getTotalSize() ); + + this.docPage = docPage; + this.entityClass = entityClass; + } + + @Override + public Iterator iterator() { + return this; + } + + @Override + public boolean hasNext() { + return docPage.hasNext(); + } + + @Override + public T next() { + JacksonDatabindHandle handle = new JacksonDatabindHandle(entityClass); + handle.getMapper().enableDefaultTyping( + ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT); + return docPage.nextContent(handle).get(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/marklogic/client/impl/PojoQueryBuilderImpl.java b/src/main/java/com/marklogic/client/impl/PojoQueryBuilderImpl.java new file mode 100644 index 000000000..78ca38b76 --- /dev/null +++ b/src/main/java/com/marklogic/client/impl/PojoQueryBuilderImpl.java @@ -0,0 +1,242 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.impl; + +import com.marklogic.client.pojo.PojoQueryBuilder; +import com.marklogic.client.query.StructuredQueryBuilder; +import com.marklogic.client.query.StructuredQueryBuilder.TextIndex; +import com.marklogic.client.query.StructuredQueryDefinition; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Date; +import java.util.HashMap; + +public class PojoQueryBuilderImpl extends StructuredQueryBuilder implements PojoQueryBuilder { + private HashMap types = new HashMap(); + private HashMap rangeIndextypes = new HashMap(); + private Class clazz; + private String classWrapper; + private boolean wrapQueries = false; + + public PojoQueryBuilderImpl(Class clazz) { + super(); + if ( clazz == null ) throw new IllegalArgumentException("clazz cannot be null"); + this.clazz = clazz; + this.classWrapper = clazz.getName(); + } + + public PojoQueryBuilderImpl(Class clazz, boolean wrapQueries) { + this(clazz); + this.wrapQueries = wrapQueries; + } + + private StructuredQueryBuilder.PathIndex pojoFieldPath(String pojoField) { + //return pathIndex("*[local-name()=\"" + classWrapper + "\"]/" + pojoField); + return pathIndex(classWrapper + "/" + pojoField); + } + + public StructuredQueryDefinition containerQuery(String pojoField, StructuredQueryDefinition query) { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + super.containerQuery(jsonProperty(pojoField), query)); + } else { + return super.containerQuery(jsonProperty(pojoField), query); + } + } + @Override + public StructuredQueryDefinition containerQuery(StructuredQueryDefinition query) { + return super.containerQuery(jsonProperty(classWrapper), query); + } + public PojoQueryBuilder containerQuery(String pojoField) { + return new PojoQueryBuilderImpl(getType(pojoField), true); + } + @Override + public StructuredQueryBuilder.GeospatialIndex + geoPair(String latitudeFieldName, String longitudeFieldName) + { + return geoElementPair(jsonProperty(classWrapper), jsonProperty(latitudeFieldName), jsonProperty(longitudeFieldName)); + } + public StructuredQueryBuilder.GeospatialIndex geoField(String pojoField) { + return geoElement(jsonProperty(pojoField)); + } + public StructuredQueryBuilder.GeospatialIndex geoPath(String pojoField) { + return geoPath(pojoFieldPath(pojoField)); + } + public StructuredQueryDefinition range(String pojoField, + StructuredQueryBuilder.Operator operator, Object... values) + { + return range(pojoFieldPath(pojoField), getRangeIndexType(pojoField), operator, values); + } + public StructuredQueryDefinition range(String pojoField, String[] options, + StructuredQueryBuilder.Operator operator, Object... values) + { + return range(pojoFieldPath(pojoField), getRangeIndexType(pojoField), options, + operator, values); + } + public StructuredQueryDefinition value(String pojoField, String... values) { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), values)); + } else { + return value(jsonProperty(pojoField), values); + } + } + public StructuredQueryDefinition value(String pojoField, Boolean value) { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), value)); + } else { + return value(jsonProperty(pojoField), value); + } + } + public StructuredQueryDefinition value(String pojoField, Number... values) { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), values)); + } else { + return value(jsonProperty(pojoField), values); + } + } + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, String... values) + { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), null, options, weight, values)); + } else { + return value(jsonProperty(pojoField), null, options, weight, values); + } + } + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, Boolean value) + { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), null, options, weight, value)); + } else { + return value(jsonProperty(pojoField), null, options, weight, value); + } + } + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, Number... values) + { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + value(jsonProperty(pojoField), null, options, weight, values)); + } else { + return value(jsonProperty(pojoField), null, options, weight, values); + } + } + public StructuredQueryDefinition word(String pojoField, String... words) { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + super.word(jsonProperty(pojoField), words)); + } else { + return super.word(jsonProperty(pojoField), words); + } + } + public StructuredQueryDefinition word(String pojoField, String[] options, + double weight, String... words) + { + if ( wrapQueries ) { + return super.containerQuery(jsonProperty(classWrapper), + super.word(jsonProperty(pojoField), null, options, weight, words)); + } else { + return super.word(jsonProperty(pojoField), null, options, weight, words); + } + } + + public String getRangeIndexType(String fieldName) { + // map java types to acceptable Range Index types + String type = rangeIndextypes.get(fieldName); + if ( type == null ) { + Class fieldClass = getType(fieldName); + if ( String.class.isAssignableFrom(fieldClass) ) { + type = "xs:string"; + } else if ( Integer.TYPE.equals(fieldClass) ) { + type = "xs:int"; + } else if ( Long.TYPE.equals(fieldClass) ) { + type = "xs:long"; + } else if ( Float.TYPE.equals(fieldClass) ) { + type = "xs:float"; + } else if ( Double.TYPE.equals(fieldClass) ) { + type = "xs:double"; + } else if ( Number.class.isAssignableFrom(fieldClass) ) { + type = "xs:decimal"; + } else if ( Date.class.isAssignableFrom(fieldClass) ) { + type = "xs:dateTime"; + } + if ( type == null ) { + throw new IllegalArgumentException("Field " + fieldName + " is not a native Java type"); + } + rangeIndextypes.put(fieldName, type); + } + return type; + } + + public Class getType(String fieldName) { + Class fieldClass = types.get(fieldName); + if ( fieldClass == null ) { + // figure out the type of the java field + String initCapPojoField = fieldName.substring(0,1).toUpperCase() + + fieldName.substring(1); + try { + fieldClass = clazz.getField(fieldName).getType(); + } catch(NoSuchFieldException e) { + Method getMethod = null; + try { + getMethod = clazz.getMethod("get" + initCapPojoField); + } catch (NoSuchMethodException e2) { + try { + getMethod = clazz.getMethod("is" + initCapPojoField); + if ( ! Boolean.class.isAssignableFrom(getMethod.getReturnType()) ) { + getMethod = null; + } + } catch (NoSuchMethodException e3) {} + } + if ( getMethod != null ) { + if ( Modifier.isStatic(getMethod.getModifiers()) ) { + throw new IllegalArgumentException("get" + initCapPojoField + + " cannot be static"); + } + fieldClass = getMethod.getReturnType(); + if ( fieldClass == Void.TYPE ) { + throw new IllegalArgumentException("get" + initCapPojoField + + " must not have return type void"); + } + } else { + String setMethodName = "set" + initCapPojoField; + for ( Method method : clazz.getMethods() ) { + if ( setMethodName.equals(method.getName()) ) { + Class[] parameters = method.getParameterTypes(); + if ( parameters != null && parameters.length == 1 ) { + fieldClass = parameters[0]; + break; + } + } + } + } + } + if ( fieldClass == null ) { + throw new IllegalArgumentException("field " + fieldName + " not found, get" + initCapPojoField + + " not found, and set" + initCapPojoField + " not found in class " + classWrapper); + } + types.put(fieldName, fieldClass); + } + return fieldClass; + } +} diff --git a/src/main/java/com/marklogic/client/impl/PojoRepositoryImpl.java b/src/main/java/com/marklogic/client/impl/PojoRepositoryImpl.java new file mode 100644 index 000000000..0f5b8604e --- /dev/null +++ b/src/main/java/com/marklogic/client/impl/PojoRepositoryImpl.java @@ -0,0 +1,353 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.impl; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.MarkLogicInternalException; +import com.marklogic.client.Transaction; +import com.marklogic.client.document.DocumentWriteSet; +import com.marklogic.client.document.JSONDocumentManager; +import com.marklogic.client.document.DocumentPage; +import com.marklogic.client.io.DocumentMetadataHandle; +import com.marklogic.client.io.Format; +import com.marklogic.client.io.JacksonDatabindHandle; +import com.marklogic.client.io.SearchHandle; +import com.marklogic.client.io.marker.SearchReadHandle; +import com.marklogic.client.pojo.PojoPage; +import com.marklogic.client.pojo.PojoQueryBuilder; +import com.marklogic.client.pojo.PojoRepository; +import com.marklogic.client.pojo.annotation.Id; +import com.marklogic.client.query.DeleteQueryDefinition; +import com.marklogic.client.query.QueryDefinition; +import com.marklogic.client.query.QueryManager; +import com.marklogic.client.query.QueryManager.QueryView; +import com.marklogic.client.query.StructuredQueryDefinition; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PojoRepositoryImpl + implements PojoRepository +{ + private final String EXTENSION = ".json"; + + private DatabaseClient client; + private Class entityClass; + private Class idClass; + private JSONDocumentManager docMgr; + private PojoQueryBuilder qb; + private Method idMethod; + private Field idField; + private String idFieldName; + + PojoRepositoryImpl(DatabaseClient client, Class entityClass) { + this.client = client; + this.entityClass = entityClass; + this.idClass = null; + this.docMgr = client.newJSONDocumentManager(); + this.docMgr.setResponseFormat(Format.JSON); + this.qb = new PojoQueryBuilderImpl(entityClass); + } + + PojoRepositoryImpl(DatabaseClient client, Class entityClass, Class idClass) { + this(client, entityClass); + this.idClass = idClass; + findId(); + if ( idMethod == null && idField == null ) { + throw new IllegalArgumentException("Your class " + entityClass.getName() + + " does not have a method or field annotated with com.marklogic.client.pojo.annotation.Id"); + } + } + + public void write(T entity) { + write(entity, null, null); + } + public void write(T entity, String... collections) { + write(entity, null, collections); + } + public void write(T entity, Transaction transaction) { + write(entity, transaction, null); + } + public void write(T entity, Transaction transaction, String... collections) { + if ( entity == null ) return; + JacksonDatabindHandle contentHandle = new JacksonDatabindHandle(entity); + contentHandle.getMapper().enableDefaultTyping( + ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT); + DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle(); + metadataHandle = metadataHandle.withCollections(entityClass.getName()); + if ( collections != null && collections.length > 0 ) { + metadataHandle = metadataHandle.withCollections(collections); + } + DocumentWriteSet writeSet = docMgr.newWriteSet(); + writeSet.add(createUri(entity), metadataHandle, contentHandle); + docMgr.write(writeSet, transaction); + } + + public boolean exists(ID id) { + return docMgr.exists(createUri(id)) != null; + } + + public long count() { + return count((QueryDefinition) null); + } + + public long count(String... collections) { + if ( collections != null && collections.length > 0 ) { + if ( collections.length > 1 || collections[0] != null ) { + return count(qb.collection(collections)); + } + } + return count((QueryDefinition) null); + } + public long count(QueryDefinition query) { + long pageLength = getPageLength(); + setPageLength(0); + PojoPage page = search(query, 1); + setPageLength(pageLength); + return page.getTotalSize(); + } + + public void delete(ID... ids) { + for ( ID id : ids ) { + docMgr.delete(createUri(id)); + } + } + public void deleteAll() { + QueryManager queryMgr = client.newQueryManager(); + DeleteQueryDefinition deleteQuery = queryMgr.newDeleteDefinition(); + deleteQuery.setCollections(entityClass.getName()); + queryMgr.delete(deleteQuery); + } + /* REST API does not currently support DELETE /search with multiple collection arguments + public void deleteAll(String... collections) { + if ( collections == null || collections.length == 0 ) { + throw new IllegalArgumentException("You must specify at least one collection"); + } else if ( collections[0] == null ) { + throw new IllegalArgumentException("Collection argument must not be null"); + } + QueryManager queryMgr = client.newQueryManager(); + DeleteQueryDefinition deleteQuery = queryMgr.newDeleteDefinition(); + deleteQuery.setCollections(collections); + queryMgr.delete((DeleteQueryDefinition) wrapQuery(deleteQuery)); + } + */ + + public T read(ID id) { + return read(id, null); + } + public T read(ID id, Transaction transaction) { + ArrayList ids = new ArrayList(); + ids.add(id); + PojoPage page = read(ids.toArray((ID[])new Serializable[0]), transaction); + if ( page == null ) return null; + Iterator iterator = page.iterator(); + if ( iterator.hasNext() ) return iterator.next(); + return null; + } + public PojoPage read(ID[] ids) { + return read(ids, null); + } + public PojoPage read(ID[] ids, Transaction transaction) { + ArrayList uris = new ArrayList(); + for ( ID id : ids ) { + uris.add(createUri(id)); + } + DocumentPage docPage = (DocumentPage) docMgr.read(transaction, uris.toArray(new String[0])); + PojoPage pojoPage = new PojoPageImpl(docPage, entityClass); + return pojoPage; + } + public PojoPage readAll(long start) { + return search(null, start, null, null); + } + public PojoPage readAll(long start, Transaction transaction) { + return search(null, start, null, transaction); + } + + public PojoPage search(long start, String... collections) { + return search(qb.collection(collections), start, null, null); + } + public PojoPage search(long start, Transaction transaction, String... collections) { + return search(qb.collection(collections), start, null, transaction); + } + + public PojoPage search(QueryDefinition query, long start) { + return search(query, start, null, null); + } + public PojoPage search(QueryDefinition query, long start, Transaction transaction) { + return search(query, start, null, transaction); + } + public PojoPage search(QueryDefinition query, long start, SearchReadHandle searchHandle) { + return search(query, start, searchHandle, null); + } + public PojoPage search(QueryDefinition query, long start, SearchReadHandle searchHandle, Transaction transaction) { + Format docMgrFormat = docMgr.getResponseFormat(); + if ( searchHandle != null ) { + HandleImplementation searchBase = HandleAccessor.checkHandle(searchHandle, "search"); + if (searchHandle instanceof SearchHandle) { + SearchHandle responseHandle = (SearchHandle) searchHandle; + if ( docMgr instanceof DocumentManagerImpl ) { + responseHandle.setHandleRegistry(((DocumentManagerImpl) docMgr).getHandleRegistry()); + } + responseHandle.setQueryCriteria(query); + } + docMgr.setResponseFormat(searchBase.getFormat()); + } else { + // TODO: remove this once REST API only considers Content-type header + // (not format parameter) for expceted payload format + docMgr.setResponseFormat(Format.XML); + } + + String tid = transaction == null ? null : transaction.getTransactionId(); + DocumentPage docPage = docMgr.search(wrapQuery(query), start, searchHandle, transaction); + docMgr.setResponseFormat(docMgrFormat); + PojoPage pojoPage = new PojoPageImpl(docPage, entityClass); + return pojoPage; + } + + public PojoQueryBuilder getQueryBuilder() { + return qb; + } + + public long getPageLength() { + return docMgr.getPageLength(); + } + public void setPageLength(long length) { + docMgr.setPageLength(length); + } + + public QueryView getSearchView() { + return docMgr.getSearchView(); + } + + public void setSearchView(QueryView view) { + docMgr.setSearchView(view); + } + + public void defineIdField(String fieldName) { + } + + public DatabaseClient getDatabaseClient() { + return client; + } + + private QueryDefinition wrapQuery(QueryDefinition query) { + if ( query == null ) { + return qb.collection(entityClass.getName()); + } else { + List collections = Arrays.asList(query.getCollections()); + HashSet collectionSet = new HashSet(collections); + collectionSet.add(entityClass.getName()); + query.setCollections(collectionSet.toArray(new String[0])); + return query; + } + } + + private String createUri(T entity) { + return createUri(getId(entity)); + } + + private String createUri(ID id) { + if ( id == null ) { + throw new IllegalStateException("id cannot be null"); + } + try { + return entityClass.getName() + "/" + URLEncoder.encode(id.toString(), "UTF-8") + EXTENSION; + } catch (UnsupportedEncodingException e) { + throw new MarkLogicInternalException(e); + } + } + + private void findId() { + if ( idMethod == null && idField == null ) { + for ( Method method : entityClass.getDeclaredMethods() ) { + if ( method.isAnnotationPresent(Id.class) ) { + Class[] parameters = method.getParameterTypes(); + if ( ! Modifier.isPublic(method.getModifiers()) ) { + throw new IllegalStateException("Your getter method, " + method.getName() + + ", annotated with com.marklogic.client.pojo.annotation.Id " + + " must be public"); + } + if ( parameters == null || parameters.length == 0 ) { + Pattern pattern = Pattern.compile("^(get|is)(.)(.*)"); + Matcher matcher = pattern.matcher(method.getName()); + if ( matcher.matches() ) { + idFieldName = matcher.group(2).toLowerCase() + matcher.group(3); + idMethod = method; + break; + } else { + throw new IllegalStateException("Your getter method, " + method.getName() + + ", annotated with com.marklogic.client.pojo.annotation.Id " + + " must be a proper getter method and begin with \"get\" or \"is\""); + } + } else { + throw new IllegalStateException("Your getter method, " + method.getName() + + ", annotated with com.marklogic.client.pojo.annotation.Id " + + " must not require any arguments"); + } + } + } + if ( idMethod == null ) { + for ( Field field : entityClass.getDeclaredFields() ) { + if ( field.isAnnotationPresent(Id.class) ) { + if ( ! Modifier.isPublic(field.getModifiers()) ) { + throw new IllegalStateException("Your field, " + field.getName() + + ", annotated with com.marklogic.client.pojo.annotation.Id " + + " must be public"); + } + idField = field; + break; + } + } + } + } + } + + private ID getId(T entity) { + findId(); + if ( idMethod != null ) { + try { + return (ID) idMethod.invoke(entity); + } catch (Exception e) { + throw new IllegalStateException("Error invoking " + entityClass.getName() + " method " + + idMethod.getName(), e); + } + } else if ( idField != null ) { + try { + return (ID) idField.get(entity); + } catch (Exception e) { + throw new IllegalStateException("Error retrieving " + entityClass.getName() + " field " + + idField.getName(), e); + } + } else { + throw new IllegalArgumentException("Your class " + entityClass.getName() + + " does not have a method or field annotated with com.marklogic.client.pojo.annotation.Id"); + } + } +} diff --git a/src/main/java/com/marklogic/client/impl/RESTServices.java b/src/main/java/com/marklogic/client/impl/RESTServices.java index c9b80d403..34b8b0873 100644 --- a/src/main/java/com/marklogic/client/impl/RESTServices.java +++ b/src/main/java/com/marklogic/client/impl/RESTServices.java @@ -74,7 +74,8 @@ public DocumentDescriptor head(RequestLogger logger, String uri, String transact throws ForbiddenUserException, FailedRequestException; public DocumentPage getBulkDocuments(RequestLogger logger, String transactionId, - Set categories, Format format, RequestParameters extraParams, String... uris) + Set categories, Format format, RequestParameters extraParams, + boolean withContent, String... uris) throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException; public DocumentPage getBulkDocuments(RequestLogger logger, QueryDefinition querydef, long start, long pageLength, String transactionId, SearchReadHandle searchHandle, diff --git a/src/main/java/com/marklogic/client/io/DocumentMetadataHandle.java b/src/main/java/com/marklogic/client/io/DocumentMetadataHandle.java index 99c78c58a..b8004652d 100644 --- a/src/main/java/com/marklogic/client/io/DocumentMetadataHandle.java +++ b/src/main/java/com/marklogic/client/io/DocumentMetadataHandle.java @@ -278,6 +278,7 @@ private PropertiesImpl() { private DocumentPermissions permissions; private DocumentProperties properties; private int quality = 0; + private boolean qualityModified = false; private ValueSerializer valueSerializer; /** @@ -407,6 +408,7 @@ public int getQuality() { */ public void setQuality(int quality) { this.quality = quality; + this.qualityModified = true; } /** * Locally specifies the match quality for the document. @@ -696,6 +698,7 @@ private void sendMetadataImpl(OutputStream out) { } } private void sendCollectionsImpl(XMLStreamWriter serializer) throws XMLStreamException { + if ( getCollections() == null || getCollections().size() == 0 ) return; serializer.writeStartElement("rapi", "collections", REST_API_NS); for (String collection: getCollections()) { @@ -707,6 +710,7 @@ private void sendCollectionsImpl(XMLStreamWriter serializer) throws XMLStreamExc serializer.writeEndElement(); } private void sendPermissionsImpl(XMLStreamWriter serializer) throws XMLStreamException { + if ( getPermissions() == null || getPermissions().size() == 0 ) return; serializer.writeStartElement("rapi", "permissions", REST_API_NS); for (Map.Entry> permission: getPermissions().entrySet()) { @@ -728,6 +732,7 @@ private void sendPermissionsImpl(XMLStreamWriter serializer) throws XMLStreamExc serializer.writeEndElement(); } private void sendPropertiesImpl(final XMLStreamWriter serializer) throws XMLStreamException, TransformerFactoryConfigurationError, TransformerException { + if ( getProperties() == null || getProperties().size() == 0 ) return; serializer.writeStartElement("prop", "properties", PROPERTY_API_NS); for (Map.Entry property: getProperties().entrySet()) { @@ -765,6 +770,7 @@ private void sendPropertiesImpl(final XMLStreamWriter serializer) throws XMLStre serializer.writeEndElement(); } private void sendQualityImpl(XMLStreamWriter serializer) throws XMLStreamException { + if ( qualityModified == false ) return; serializer.writeStartElement("rapi", "quality", REST_API_NS); serializer.writeCharacters(String.valueOf(getQuality())); serializer.writeEndElement(); diff --git a/src/main/java/com/marklogic/client/io/JacksonDatabindHandle.java b/src/main/java/com/marklogic/client/io/JacksonDatabindHandle.java new file mode 100644 index 000000000..4f0dd2791 --- /dev/null +++ b/src/main/java/com/marklogic/client/io/JacksonDatabindHandle.java @@ -0,0 +1,185 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.io; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.marklogic.client.MarkLogicIOException; +import com.marklogic.client.io.marker.ContentHandle; +import com.marklogic.client.io.marker.ContentHandleFactory; +import com.marklogic.client.impl.JacksonBaseHandle; + +/** + * An adapter for using the Jackson Open Source library for JSON; represents + * JSON content as a Jackson JsonNode for reading or writing. Enables reading and + * writing JSON documents, JSON structured search, and other JSON input and output. + */ +public class JacksonDatabindHandle + extends JacksonBaseHandle + implements ContentHandle +{ + private Class contentClass; + private T content; + + /** + * Creates a factory to create a JacksonDatabindHandle instance for POJO instances + * of the specified classes. + * @param pojoClasses the POJO classes for which this factory provides a handle + * @return the factory + */ + static public ContentHandleFactory newFactory(Class... pojoClasses) { + if (pojoClasses == null || pojoClasses.length == 0) return null; + return new JacksonDatabindHandleFactory(pojoClasses); + } + /** + * Creates a factory to create a JacksonDatabindHandle instance for POJO instances + * of the specified classes. + * @param mapper the Jackson ObjectMapper for marshaling the POJO classes + * @param pojoClasses the POJO classes for which this factory provides a handle + * @return the factory + */ + static public ContentHandleFactory newFactory(ObjectMapper mapper, Class... pojoClasses) { + if (mapper == null || pojoClasses == null || pojoClasses.length == 0) return null; + return new JacksonDatabindHandleFactory(mapper, pojoClasses); + } + + /** + * Specify the type of content this JacksonDatabindHandle will manage. + * + * @param contentClass the class of your custom Pojo for databinding + */ + public JacksonDatabindHandle(Class contentClass) { + super(); + this.contentClass = contentClass; + setResendable(true); + } + /** + * Provides a handle on JSON content as a Jackson tree. + * @param content the JSON root node of the tree. + */ + public JacksonDatabindHandle(T content) { + this((Class) content.getClass()); + set(content); + } + + /** + * Specifies the format of the content and returns the handle + * as a fluent convenience. + * @param format the format of the content + * @return this handle + */ + public JacksonDatabindHandle withFormat(Format format) { + setFormat(format); + return this; + } + + /** + * Returns the root node of the JSON tree. + * @return the JSON root node. + */ + @Override + public T get() { + return content; + } + /** + * Assigns your custom Pojo as the content. + * @param content your custom Pojo + */ + @Override + public void set(T content) { + this.content = content; + } + /** + * Assigns a JSON tree as the content and returns the handle. + * @param content the JSON root node. + * @return the handle on the JSON tree. + */ + public JacksonDatabindHandle with(T content) { + set(content); + return this; + } + + @Override + protected void receiveContent(InputStream content) { + if (content == null) + return; + + try { + this.content = (T) getMapper().readValue( + new InputStreamReader(content, "UTF-8"), contentClass); + } catch (JsonParseException e) { + throw new MarkLogicIOException(e); + } catch (JsonMappingException e) { + throw new MarkLogicIOException(e); + } catch (IOException e) { + throw new MarkLogicIOException(e); + } + + } + @Override + protected boolean hasContent() { + return content != null; + } + @Override + public void write(OutputStream out) throws IOException { + getMapper().writeValue(new OutputStreamWriter(out, "UTF-8"), get()); + } + + static private class JacksonDatabindHandleFactory implements ContentHandleFactory { + private Class[] contentClasses; + private ObjectMapper mapper = null; + private Set> classSet; + + private JacksonDatabindHandleFactory(Class... contentClasses) { + this(null, contentClasses); + } + + private JacksonDatabindHandleFactory(ObjectMapper mapper, Class... contentClasses) { + super(); + this.contentClasses = contentClasses; + this.mapper = mapper; + this.classSet = new HashSet>(Arrays.asList(contentClasses)); + } + + @Override + public Class[] getHandledClasses() { + return contentClasses; + } + @Override + public boolean isHandled(Class type) { + return classSet.contains(type); + } + @Override + public ContentHandle newHandle(Class type) { + if ( ! isHandled(type) ) return null; + JacksonDatabindHandle handle = new JacksonDatabindHandle(type); + if ( mapper != null ) handle.setMapper(mapper); + return handle; + } + } +} diff --git a/src/main/java/com/marklogic/client/io/JacksonHandle.java b/src/main/java/com/marklogic/client/io/JacksonHandle.java index c0f44e50a..866479a10 100644 --- a/src/main/java/com/marklogic/client/io/JacksonHandle.java +++ b/src/main/java/com/marklogic/client/io/JacksonHandle.java @@ -16,29 +16,20 @@ package com.marklogic.client.io; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; + import com.marklogic.client.MarkLogicIOException; -import com.marklogic.client.io.BaseHandle; -import com.marklogic.client.io.Format; -import com.marklogic.client.io.OutputStreamSender; -import com.marklogic.client.io.marker.BufferableHandle; import com.marklogic.client.io.marker.ContentHandle; import com.marklogic.client.io.marker.ContentHandleFactory; -import com.marklogic.client.io.marker.JSONReadHandle; -import com.marklogic.client.io.marker.JSONWriteHandle; -import com.marklogic.client.io.marker.StructureReadHandle; -import com.marklogic.client.io.marker.StructureWriteHandle; +import com.marklogic.client.impl.JacksonBaseHandle; /** * An adapter for using the Jackson Open Source library for JSON; represents @@ -46,13 +37,10 @@ * writing JSON documents, JSON structured search, and other JSON input and output. */ public class JacksonHandle - extends BaseHandle - implements OutputStreamSender, BufferableHandle, ContentHandle, - JSONReadHandle, JSONWriteHandle, - StructureReadHandle, StructureWriteHandle + extends JacksonBaseHandle + implements ContentHandle { private JsonNode content; - private ObjectMapper mapper; /** * Creates a factory to create a JacksonHandle instance for a JSON node. @@ -83,7 +71,6 @@ public ContentHandle newHandle(Class type) { */ public JacksonHandle() { super(); - super.setFormat(Format.JSON); setResendable(true); } /** @@ -96,13 +83,14 @@ public JacksonHandle(JsonNode content) { } /** - * Returns the mapper used to construct node objects from JSON. - * @return the JSON mapper. + * Specifies the format of the content and returns the handle + * as a fluent convenience. + * @param format the format of the content + * @return this handle */ - public ObjectMapper getMapper() { - if (mapper == null) - mapper = new ObjectMapper(); - return mapper; + public JacksonHandle withFormat(Format format) { + setFormat(format); + return this; } /** @@ -131,63 +119,15 @@ public JacksonHandle with(JsonNode content) { return this; } - /** - * Restricts the format to JSON. - */ - @Override - public void setFormat(Format format) { - if (format != Format.JSON) - throw new IllegalArgumentException( - "JacksonHandle supports the JSON format only"); - } - - @Override - public void fromBuffer(byte[] buffer) { - if (buffer == null || buffer.length == 0) - content = null; - else - receiveContent(new ByteArrayInputStream(buffer)); - } - @Override - public byte[] toBuffer() { - try { - if (content == null) - return null; - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - write(buffer); - - return buffer.toByteArray(); - } catch (IOException e) { - throw new MarkLogicIOException(e); - } - } - - /** - * Returns the JSON tree as a string. - */ - @Override - public String toString() { - try { - return new String(toBuffer(),"UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new MarkLogicIOException(e); - } - } - - @Override - protected Class receiveAs() { - return InputStream.class; - } @Override protected void receiveContent(InputStream content) { if (content == null) return; try { - this.content = getMapper().readValue( + set( getMapper().readValue( new InputStreamReader(content, "UTF-8"), JsonNode.class - ); + )); } catch (JsonParseException e) { throw new MarkLogicIOException(e); } catch (JsonMappingException e) { @@ -198,14 +138,11 @@ protected void receiveContent(InputStream content) { } @Override - protected OutputStreamSender sendContent() { - if (content == null) { - throw new IllegalStateException("No document to write"); - } - return this; + protected boolean hasContent() { + return content != null; } @Override public void write(OutputStream out) throws IOException { - getMapper().writeValue(new OutputStreamWriter(out, "UTF-8"), content); + getMapper().writeValue(new OutputStreamWriter(out, "UTF-8"), get()); } } diff --git a/src/main/java/com/marklogic/client/io/JacksonParserHandle.java b/src/main/java/com/marklogic/client/io/JacksonParserHandle.java new file mode 100644 index 000000000..28e0a6e50 --- /dev/null +++ b/src/main/java/com/marklogic/client/io/JacksonParserHandle.java @@ -0,0 +1,155 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.marklogic.client.MarkLogicIOException; +import com.marklogic.client.io.marker.ContentHandle; +import com.marklogic.client.io.marker.ContentHandleFactory; +import com.marklogic.client.io.marker.GenericReadHandle; +import com.marklogic.client.io.marker.JSONReadHandle; +import com.marklogic.client.io.marker.OperationNotSupported; +import com.marklogic.client.io.marker.StructureReadHandle; +import com.marklogic.client.io.marker.TextReadHandle; +import com.marklogic.client.io.marker.XMLReadHandle; +import com.marklogic.client.impl.JacksonBaseHandle; + +/** + * An adapter for using the streaming capabilities of the Jackson Open Source library. + * Enables low-level reading and writing of JSON documents. + */ +// TODO: add link to jackson streaming documentation +public class JacksonParserHandle + extends JacksonBaseHandle + implements ContentHandle +{ + private ObjectMapper mapper; + private JsonParser parser = null; + private InputStream content = null; + + final static private int BUFFER_SIZE = 8192; + + /** + * Creates a factory to create a JacksonParserHandle instance for a JsonParser. + * @return the factory + */ + static public ContentHandleFactory newFactory() { + return new ContentHandleFactory() { + @Override + public Class[] getHandledClasses() { + return new Class[]{ JsonParser.class }; + } + @Override + public boolean isHandled(Class type) { + return JsonParser.class.isAssignableFrom(type); + } + @Override + public ContentHandle newHandle(Class type) { + @SuppressWarnings("unchecked") + ContentHandle handle = isHandled(type) ? + (ContentHandle) new JacksonParserHandle() : null; + return handle; + } + }; + } + + public JacksonParserHandle() { + super(); + setFormat(Format.JSON); + setResendable(false); + } + + /** + * Specifies the format of the content and returns the handle + * as a fluent convenience. + * @param format the format of the content + * @return this handle + */ + public JacksonParserHandle withFormat(Format format) { + setFormat(format); + return this; + } + + /** + * JsonParser allows streaming access to content as it arrives. + */ + public JsonParser get() { + if ( parser == null ) { + if ( content == null ) { + throw new IllegalStateException("Handle is not yet populated with content"); + } + try { + parser = getMapper().getFactory().createParser(content); + } catch (JsonParseException e) { + throw new MarkLogicIOException(e); + } catch (IOException e) { + throw new MarkLogicIOException(e); + } + } + return parser; + } + /** + * Available for the edge case that content from a JsonParser must be written. + */ + public void set(JsonParser parser) { + this.parser = parser; + if ( parser == null ) { + content = null; + } else if ( parser.getInputSource() instanceof InputStream ) { + content = (InputStream) parser.getInputSource(); + } + } + + @Override + protected void receiveContent(InputStream content) { + this.content = content; + if (content == null) parser = null; + } + protected boolean hasContent() { + return content != null || parser != null; + } + @Override + public void write(OutputStream out) throws IOException { + try { + if ( parser != null && parser.nextToken() != null ) { + JsonGenerator generator = getMapper().getFactory().createGenerator(out); + generator.copyCurrentStructure(parser); + generator.close(); + } else if (content != null) { + byte[] b = new byte[BUFFER_SIZE]; + int len = 0; + while ((len = content.read(b)) != -1) { + out.write(b, 0, len); + } + content.close(); + } + } catch (IOException e) { + throw new MarkLogicIOException(e); + } + } +} diff --git a/src/main/java/com/marklogic/client/pojo/PojoPage.java b/src/main/java/com/marklogic/client/pojo/PojoPage.java new file mode 100644 index 000000000..94b866eae --- /dev/null +++ b/src/main/java/com/marklogic/client/pojo/PojoPage.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.pojo; + +import com.marklogic.client.Page; + +/** Enables pagination over objects retrieved from the server and deserialized by + * PojoRepository read and search methods. + */ +public interface PojoPage extends Page {} diff --git a/src/main/java/com/marklogic/client/pojo/PojoQueryBuilder.java b/src/main/java/com/marklogic/client/pojo/PojoQueryBuilder.java new file mode 100644 index 000000000..7b44372f1 --- /dev/null +++ b/src/main/java/com/marklogic/client/pojo/PojoQueryBuilder.java @@ -0,0 +1,208 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.pojo; + +import javax.xml.namespace.QName; + +import com.marklogic.client.query.RawStructuredQueryDefinition; +import com.marklogic.client.query.StructuredQueryBuilder; +import com.marklogic.client.query.StructuredQueryDefinition; +import com.marklogic.client.util.IterableNamespaceContext; + +/** Extends StructuredQueryBuilder with convenience methods specific to working with pojos. + * The goal of {@link com.marklogic.client.pojo the pojo facade} is to simplify working with + * custom pojos. PojoQueryBuilder keeps all the powerful queries available via + * StructuredQueryBuilder while enabling queries across objects persisted using + * {@link PojoRepository}. + * + *

For methods which accept a "pojoField" argument and for {@link #geoField geoField}, we are refering to + * fields (or properties) appropriate for + * JavaBeans, + * including fields accessible via public getters and setters, or public fields.

+ * + * + *

Where StructuredQueryBuilder accepts StructuredQueryBuilder.TextIndex as a first argument + * to + * {@link #value(StructuredQueryBuilder.TextIndex, String...) value(TextIndex, String...)} + * and + * {@link #word(StructuredQueryBuilder.TextIndex, String...) word(TextIndex, String...)} + * methods, + * PojoQueryBuilder adds shortcut methods which accept as the first argument a String name of the + * pojoField. Similarly, PojoQueryBuilder accepts String pojoField arguments wherever + * StructuredQueryBuilder accepts StructuredQueryBuilder.Element, + * StructuredQueryBuilder.Attribute, and StructuredQueryBuilder.PathIndex + * as arguments to + * {@link #geoAttributePair(StructuredQueryBuilder.Element, StructuredQueryBuilder.Attribute, + * StructuredQueryBuilder.Attribute) + * geoAttributePair(Element, Attribute, Attribute)}, + * {@link #geoElement(StructuredQueryBuilder.Element) + * geoElement(Element)}, + * {@link #geoElement(StructuredQueryBuilder.Element, StructuredQueryBuilder.Element) + * geoElement(Element, Element)}, + * {@link #geoElementPair(StructuredQueryBuilder.Element, StructuredQueryBuilder.Element, + * StructuredQueryBuilder.Element) + * geoElementPair(Element, Element, Element)}, + * {@link #geoPath(StructuredQueryBuilder.PathIndex) + * geoPath(PathIndex)} + *

+ * + *

Here are a couple examples. Without the pojo facade you might persist your products using + * {@link com.marklogic.client.io.JacksonDatabindHandle JacksonDatabindHandle} and query the + * json property thusly:

+ *
{@code    StructuredQueryBuilder sqb = new StructuredQueryBuilder();
+ *    QueryDefinition query = sqb.value(sqb.jsonProperty("productId"), 12345);}
+ * + *

If you use {@link PojoRepository} to persist your products, you can query more simply:

+ *
{@code    PojoQueryBuilder pqb = pojoRepository.getQueryBuilder();
+ *    QueryDefinition query = pqb.value("productId", 12345);}
+ * + *

Similarly, without the pojo facade you might persist your pojos using + * {@link com.marklogic.client.io.JAXBHandle JAXBHandle} and if they + * have a geoPosition field which is an object with latitude and longitude pojoFields + * (which persist as elements) you might query them thusly:

+ *
{@code    StructuredQueryBuilder sqb = new StructuredQueryBuilder();
+ *    StructuredQueryBuilder.GeospatialIndex geoIdx = sqb.geoElementPair(
+ *      sqb.element("geoPosition"), sqb.element("latitude"), sqb.element("longitude"));}
+ * + *

But if you use {@link PojoRepository} to persist your pojos with a latitude and longitude + * pojoFields, you can query them more simply:

+ *
{@code    PojoQueryBuilder pqb = pojoRepository.getQueryBuilder();
+ *    StructuredQueryBuilder.GeospatialIndex geoIdx = 
+ *      pqb.geoPair("latitude", "longitude");}
+ * + *

As custom pojos may have nested pojos, PojoQueryBuilder also makes it easy to query + * those nested pojos. For example, if you had the following classes:

+ *
    class City {
+ *     {@literal @}Id int id;
+ *      Country country;
+ *      int getId();
+ *      void setId(int id);
+ *      Country getCountry();
+ *      void setCountry(Country country);
+ *    }
+ *    class Country {
+ *      String continent;
+ *      String getContinent();
+ *      void setContinent();
+ *    }
+ * + *

That is, you have a pojo class City with a field "country" of type + * Country, you could query fields on the nested country thusly:

+ *
{@code    PojoRepository cities = 
+ *      databaseClient.newPojoRepository(City.class, Integer.class);
+ *    PojoQueryBuilder citiesQb = cities.getQueryBuilder();
+ *    PojoQueryBuilder countriesQb = citiesQb.containerQuery("country");
+ *    QueryDefinition query = countriesQb.value("continent", "EU"); }
+ */ +public interface PojoQueryBuilder { + public StructuredQueryDefinition containerQuery(String pojoField, + StructuredQueryDefinition query); + public StructuredQueryDefinition containerQuery(StructuredQueryDefinition query); + public PojoQueryBuilder containerQuery(String pojoField); + public StructuredQueryBuilder.GeospatialIndex + geoPair(String latitudeFieldName, String longitudeFieldName); + /** + * NOTE: Since the pojo facade abstracts away the persistence details, "field" here refers + * to a pojoField like all other convenience methods in PojoQueryBuilder,not + * a MarkLogic field specified on the server. + * @param pojoField the name of a field (or getter or setter) on class T + */ + public StructuredQueryBuilder.GeospatialIndex + geoField(String pojoField); + public StructuredQueryBuilder.GeospatialIndex + geoPath(String pojoField); + public StructuredQueryDefinition range(String pojoField, + StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(String pojoField, String[] options, + StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition value(String pojoField, String... values); + public StructuredQueryDefinition value(String pojoField, Boolean value); + public StructuredQueryDefinition value(String pojoField, Number... values); + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, String... values); + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, Boolean value); + public StructuredQueryDefinition value(String pojoField, String[] options, + double weight, Number... values); + public StructuredQueryDefinition word(String pojoField, String... words); + public StructuredQueryDefinition word(String pojoField, String[] options, + double weight, String... words); + + // All following method signatures copied from StructuredQueryBuilder since it has no interface we can extend + public StructuredQueryDefinition and(StructuredQueryDefinition... queries); + public StructuredQueryDefinition andNot(StructuredQueryDefinition positive, StructuredQueryDefinition negative); + public StructuredQueryBuilder.Attribute attribute(QName qname); + public StructuredQueryBuilder.Attribute attribute(String name); + public StructuredQueryDefinition boost(StructuredQueryDefinition matchingQuery, StructuredQueryDefinition boostingQuery); + public StructuredQueryBuilder.Region box(double south, double west, double north, double east); + public RawStructuredQueryDefinition build(StructuredQueryDefinition... queries); + public StructuredQueryBuilder.Region circle(double latitude, double longitude, double radius); + public StructuredQueryBuilder.Region circle(StructuredQueryBuilder.Point center, double radius); + public StructuredQueryDefinition collection(String... uris); + public StructuredQueryDefinition collectionConstraint(String constraintName, String... uris); + public StructuredQueryDefinition containerConstraint(String constraintName, StructuredQueryDefinition query); + public StructuredQueryDefinition containerQuery(StructuredQueryBuilder.ContainerIndex index, StructuredQueryDefinition query); + public StructuredQueryDefinition customConstraint(String constraintName, String... text); + public StructuredQueryDefinition directory(boolean isInfinite, String... uris); + public StructuredQueryDefinition directory(int depth, String... uris); + public StructuredQueryDefinition document(String... uris); + public StructuredQueryDefinition documentFragment(StructuredQueryDefinition query); + public StructuredQueryBuilder.Element element(QName qname); + public StructuredQueryBuilder.Element element(String name); + public StructuredQueryBuilder.ElementAttribute elementAttribute(StructuredQueryBuilder.Element element, StructuredQueryBuilder.Attribute attribute); + public StructuredQueryDefinition elementConstraint(String constraintName, StructuredQueryDefinition query); + public StructuredQueryBuilder.Field field(String name); + public StructuredQueryBuilder.GeospatialIndex geoAttributePair(StructuredQueryBuilder.Element parent, StructuredQueryBuilder.Attribute lat, StructuredQueryBuilder.Attribute lon); + public StructuredQueryBuilder.GeospatialIndex geoElement(StructuredQueryBuilder.Element element); + public StructuredQueryBuilder.GeospatialIndex geoElement(StructuredQueryBuilder.Element parent, StructuredQueryBuilder.Element element); + public StructuredQueryBuilder.GeospatialIndex geoElementPair(StructuredQueryBuilder.Element parent, StructuredQueryBuilder.Element lat, StructuredQueryBuilder.Element lon); + public StructuredQueryBuilder.GeospatialIndex geoPath(StructuredQueryBuilder.PathIndex pathIndex); + public StructuredQueryDefinition geospatial(StructuredQueryBuilder.GeospatialIndex index, StructuredQueryBuilder.FragmentScope scope, String[] options, StructuredQueryBuilder.Region... regions); + public StructuredQueryDefinition geospatial(StructuredQueryBuilder.GeospatialIndex index, StructuredQueryBuilder.Region... regions); + public StructuredQueryDefinition geospatialConstraint(String constraintName, StructuredQueryBuilder.Region... regions); + public IterableNamespaceContext getNamespaces(); + public StructuredQueryDefinition locks(StructuredQueryDefinition query); + public StructuredQueryDefinition near(int distance, double weight, StructuredQueryBuilder.Ordering order, StructuredQueryDefinition... queries); + public StructuredQueryDefinition near(StructuredQueryDefinition... queries); + public StructuredQueryDefinition not(StructuredQueryDefinition query); + public StructuredQueryDefinition notIn(StructuredQueryDefinition positive, StructuredQueryDefinition negative); + public StructuredQueryDefinition or(StructuredQueryDefinition... queries); + public StructuredQueryBuilder.PathIndex pathIndex(String path); + public StructuredQueryBuilder.Region point(double latitude, double longitude); + public StructuredQueryBuilder.Region polygon(StructuredQueryBuilder.Point... points); + public StructuredQueryDefinition properties(StructuredQueryDefinition query); + public StructuredQueryDefinition propertiesConstraint(String constraintName, StructuredQueryDefinition query); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, String[] options, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, String collation, String[] options, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, String collation, StructuredQueryBuilder.FragmentScope scope, String[] options, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, String collation, StructuredQueryBuilder.FragmentScope scope, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, String collation, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition range(StructuredQueryBuilder.RangeIndex index, String type, StructuredQueryBuilder.Operator operator, Object... values); + public StructuredQueryDefinition rangeConstraint(String constraintName, StructuredQueryBuilder.Operator operator, String... values); + public String[] rangeOptions(String... options); + public void setNamespaces(IterableNamespaceContext namespaces); + public StructuredQueryDefinition term(double weight, String... terms); + public StructuredQueryDefinition term(String... terms); + public StructuredQueryDefinition value(StructuredQueryBuilder.TextIndex index, String... values); + public StructuredQueryDefinition value(StructuredQueryBuilder.TextIndex index, StructuredQueryBuilder.FragmentScope scope, String[] options, double weight, String... values); + public StructuredQueryDefinition valueConstraint(String constraintName, double weight, String... values); + public StructuredQueryDefinition valueConstraint(String constraintName, String... values); + public StructuredQueryDefinition word(StructuredQueryBuilder.TextIndex index, String... words); + public StructuredQueryDefinition word(StructuredQueryBuilder.TextIndex index, StructuredQueryBuilder.FragmentScope scope, String[] options, double weight, String... words); + public StructuredQueryDefinition wordConstraint(String constraintName, double weight, String... words); + public StructuredQueryDefinition wordConstraint(String constraintName, String... words); +} + diff --git a/src/main/java/com/marklogic/client/pojo/PojoRepository.java b/src/main/java/com/marklogic/client/pojo/PojoRepository.java new file mode 100644 index 000000000..a3548dbd6 --- /dev/null +++ b/src/main/java/com/marklogic/client/pojo/PojoRepository.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.pojo; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.Transaction; +import com.marklogic.client.io.marker.SearchReadHandle; +import com.marklogic.client.query.QueryDefinition; + +import java.io.Serializable; + +public interface PojoRepository { + public void write(T entity); + public void write(T entity, String... collections); + public void write(T entity, Transaction transaction); + public void write(T entity, Transaction transaction, String... collections); + + public boolean exists(ID id); + + public long count(); + public long count(String... collection); + public long count(QueryDefinition query); + + public void delete(ID... ids); + public void deleteAll(); + /* REST API does not currently support DELETE /search with multiple collection arguments + public void deleteAll(String... collections); + */ + + public T read(ID id); + public T read(ID id, Transaction transaction); + public PojoPage read(ID[] ids); + public PojoPage read(ID[] ids, Transaction transaction); + public PojoPage readAll(long start); + public PojoPage readAll(long start, Transaction transaction); + + public PojoPage search(long start, String... collections); + public PojoPage search(long start, Transaction transaction, String... collections); + public PojoPage search(QueryDefinition query, long start); + public PojoPage search(QueryDefinition query, long start, Transaction transaction); + public PojoPage search(QueryDefinition query, long start, SearchReadHandle searchHandle); + public PojoPage search(QueryDefinition query, long start, SearchReadHandle searchHandle, Transaction transaction); + + public PojoQueryBuilder getQueryBuilder(); + + public long getPageLength(); // default: 50 + public void setPageLength(long length); + + public void defineIdField(String fieldName); + + public DatabaseClient getDatabaseClient(); +} diff --git a/src/main/java/com/marklogic/client/pojo/annotation/Id.java b/src/main/java/com/marklogic/client/pojo/annotation/Id.java new file mode 100644 index 000000000..42cf1dfda --- /dev/null +++ b/src/main/java/com/marklogic/client/pojo/annotation/Id.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.pojo.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Id { +} diff --git a/src/main/java/com/marklogic/client/pojo/package-info.java b/src/main/java/com/marklogic/client/pojo/package-info.java new file mode 100644 index 000000000..fd6d0af83 --- /dev/null +++ b/src/main/java/com/marklogic/client/pojo/package-info.java @@ -0,0 +1,24 @@ +/** + * The goal of this package (sometimes referred to as "the pojo facade" is to simplify working + * with custom Plain Old Java Objects (pojos) without hassling with persistence details. + * {@link com.marklogic.client.pojo.PojoRepository} simplifies create, read, update, and delete + * (CRUD) operations on custom pojos. {@link com.marklogic.client.pojo.PojoQueryBuilder} keeps + * all the powerful queries available via StructuredQueryBuilder while enabling queries across + * objects persisted using PojoRepository. + */ +/* + * Copyright 2012-2014 MarkLogic Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.marklogic.client.pojo; diff --git a/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java b/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java index bfc52aa18..2a839d6f4 100644 --- a/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java +++ b/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java @@ -146,9 +146,9 @@ public interface ElementAttribute extends RangeIndex, TextIndex { public interface Field extends RangeIndex, TextIndex { } /** - * A JSONKey represents a key in JSON database documents. + * A JSONProperty represents a key in JSON database documents. */ - public interface JSONKey extends ContainerIndex, RangeIndex, TextIndex { + public interface JSONProperty extends Element, ContainerIndex, RangeIndex, TextIndex { } /** * A PathIndex represents an index defined with an XPath @@ -389,7 +389,7 @@ public TermQuery term(double weight, String... terms) { /** * Matches an element, attribute, json key, or field - * that has a value with the same words as at least one + * that has a value with the same string value as at least one * of the criteria values. * @param index the value container * @param values the possible values to match @@ -400,7 +400,29 @@ public StructuredQueryDefinition value(TextIndex index, String... values) { } /** * Matches an element, attribute, json key, or field - * that has a value with the same words as at least one + * that has a value with the same boolean value as at least one + * of the criteria values. + * @param index the value container + * @param value either true or false + * @return the StructuredQueryDefinition for the value query + */ + public StructuredQueryDefinition value(TextIndex index, Boolean value) { + return new ValueQuery(index, null, null, null, new Object[] {value}); + } + /** + * Matches an element, attribute, json key, or field + * that has a value with the same numeric value as at least one + * of the criteria values. + * @param index the value container + * @param values the possible values to match + * @return the StructuredQueryDefinition for the value query + */ + public StructuredQueryDefinition value(TextIndex index, Number... values) { + return new ValueQuery(index, null, null, null, values); + } + /** + * Matches an element, attribute, json key, or field + * that has a value with the same string value as at least one * of the criteria values. * @param index the value container * @param scope whether the query matches the document content or properties @@ -412,6 +434,34 @@ public StructuredQueryDefinition value(TextIndex index, String... values) { public StructuredQueryDefinition value(TextIndex index, FragmentScope scope, String[] options, double weight, String... values) { return new ValueQuery(index, scope, options, weight, values); } + /** + * Matches an element, attribute, json key, or field + * that has a value with the same boolean value as at least one + * of the criteria values. + * @param index the value container + * @param scope whether the query matches the document content or properties + * @param options options for fine tuning the query + * @param weight the multiplier for the match in the document ranking + * @param value either true or false + * @return the StructuredQueryDefinition for the value query + */ + public StructuredQueryDefinition value(TextIndex index, FragmentScope scope, String[] options, double weight, Boolean value) { + return new ValueQuery(index, scope, options, weight, new Object[] {value}); + } + /** + * Matches an element, attribute, json key, or field + * that has a value with the same numeric value as at least one + * of the criteria values. + * @param index the value container + * @param scope whether the query matches the document content or properties + * @param options options for fine tuning the query + * @param weight the multiplier for the match in the document ranking + * @param values the possible values to match + * @return the StructuredQueryDefinition for the value query + */ + public StructuredQueryDefinition value(TextIndex index, FragmentScope scope, String[] options, double weight, Number... values) { + return new ValueQuery(index, scope, options, weight, values); + } /** * Matches an element, attribute, json key, or field @@ -614,8 +664,8 @@ public Field field(String name) { * @param name the name of the JSON key * @return the identifier for the JSON key */ - public JSONKey jsonKey(String name) { - return new JSONKeyImpl(name); + public JSONProperty jsonProperty(String name) { + return new JSONPropertyImpl(name); } /** * Identifies a path index to match with a query. @@ -783,7 +833,7 @@ public CollectionConstraintQuery collectionConstraint(String constraintName, Str /** * Matches the container specified by the constraint when it - * has a value with the same words as at least one + * has a value with the same string value as at least one * of the criteria values. * @param constraintName the constraint definition * @param values the possible values to match @@ -794,7 +844,7 @@ public ValueConstraintQuery valueConstraint(String constraintName, String... val } /** * Matches the container specified by the constraint when it - * has a value with the same words as at least one + * has a value with the same string value as at least one * of the criteria values. * @param constraintName the constraint definition * @param weight the multiplier for the match in the document ranking @@ -1636,16 +1686,48 @@ void innerSerialize(XMLStreamWriter serializer) throws Exception { } class ValueQuery - extends TextQuery { - ValueQuery(TextIndex index, FragmentScope scope, - String[] options, Double weight, String[] values) { - super(index, scope, options, weight, values); - } - @Override - void innerSerialize(XMLStreamWriter serializer) throws Exception { - serializer.writeStartElement("value-query"); - super.innerSerialize(serializer); - serializer.writeEndElement(); + extends AbstractStructuredQuery { + TextIndex index; + FragmentScope scope; + String[] options; + Double weight; + Object[] values; + ValueQuery(TextIndex index, FragmentScope scope, + String[] options, Double weight, Object[] values) { + this.index = index; + this.scope = scope; + this.options = options; + this.weight = weight; + this.values = values; + } + void innerSerialize(XMLStreamWriter serializer) throws Exception { + serializer.writeStartElement("value-query"); + ((IndexImpl) index).innerSerialize(serializer); + if (scope != null) { + if (scope == FragmentScope.DOCUMENT) { + writeText(serializer, "fragment-scope", "documents"); + } + else { + writeText(serializer, "fragment-scope", + scope.toString().toLowerCase()); + } + } + if ( values != null ) { + for ( Object value: values ) { + if ( value == null ) { + serializer.writeEmptyElement("null"); + } else if ( value instanceof String ) { + writeText(serializer, "text", value); + } else if ( value instanceof Number ) { + writeText(serializer, "number", value); + } else if ( value instanceof Boolean ) { + writeText(serializer, "boolean", value); + } + } + } + writeTextList(serializer, "term-option", options); + writeText(serializer, "weight", weight); + serializer.writeEndElement(); } } @@ -1814,14 +1896,14 @@ void innerSerialize(XMLStreamWriter serializer) throws Exception { serializer.writeEndElement(); } } - class JSONKeyImpl extends IndexImpl implements JSONKey { + class JSONPropertyImpl extends IndexImpl implements JSONProperty { String name; - JSONKeyImpl(String name) { + JSONPropertyImpl(String name) { this.name = name; } @Override void innerSerialize(XMLStreamWriter serializer) throws Exception { - writeText(serializer, "json-key", name); + writeText(serializer, "json-property", name); } } class PathIndexImpl extends IndexImpl implements PathIndex { @@ -1847,12 +1929,20 @@ class GeoElementImpl extends IndexImpl implements GeospatialIndex { } @Override void innerSerialize(XMLStreamWriter serializer) throws Exception { - if (parent != null) { + if (parent != null && parent instanceof ElementImpl) { ElementImpl parentImpl = (ElementImpl) parent; serializeNamedIndex(serializer, "parent", parentImpl.qname, parentImpl.name); + } else if (parent != null && parent instanceof IndexImpl) { + IndexImpl parentImpl = (IndexImpl) parent; + parentImpl.innerSerialize(serializer); + } + if ( element instanceof ElementImpl ) { + ElementImpl elementImpl = (ElementImpl) element; + serializeNamedIndex(serializer, "element", elementImpl.qname, elementImpl.name); + } else if ( element instanceof IndexImpl ) { + IndexImpl indexImpl = (IndexImpl) element; + indexImpl.innerSerialize(serializer); } - ElementImpl elementImpl = (ElementImpl) element; - serializeNamedIndex(serializer, "element", elementImpl.qname, elementImpl.name); } } class GeoElementPairImpl extends IndexImpl implements GeospatialIndex { @@ -2252,6 +2342,7 @@ static private void writeTextList(XMLStreamWriter serializer, return; } for (Object object: objects) { + if ( object == null ) continue; serializer.writeStartElement(container); serializer.writeCharacters( (object instanceof String) ? diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index 86deb9bc7..ed0e090d5 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -287,7 +287,6 @@

Registering New IO Representations for Shortcut Methods

To use extra IO handles like {@link com.marklogic.client.extra.dom4j.DOM4JHandle}, {@link com.marklogic.client.extra.gson.GSONHandle}, - {@link com.marklogic.client.extra.jackson.JacksonHandle}, {@link com.marklogic.client.extra.jdom.JDOMHandle}, or {@link com.marklogic.client.extra.xom.XOMHandle}, you download the library integrated by the handle and add the library to the classpath. @@ -296,10 +295,11 @@

Registering New IO Representations for Shortcut Methods

using {@link com.marklogic.client.DatabaseClientFactory}.getHandleRegistry().

- You can also register a factory for the built-in JAXB handle to support - IO on your POJO classes in shortcut methods. The following example + You can also register a factory for the built-in JAXB and JacksonDatabind handles + to support IO on your POJO classes in shortcut methods. The following example registers the JAXB handle for one or more POJO classes and writes - and reads the POJOs as database documents. + and reads the POJOs as database documents. The same pattern works with + JacksonDatabindHandle.

 // configure once before creating a client
diff --git a/src/test/java/com/marklogic/client/test/AlertingTest.java b/src/test/java/com/marklogic/client/test/AlertingTest.java
index 5d1de3df7..a95781a02 100644
--- a/src/test/java/com/marklogic/client/test/AlertingTest.java
+++ b/src/test/java/com/marklogic/client/test/AlertingTest.java
@@ -309,7 +309,7 @@ public void testJSONRuleDefinitions()
 		BytesHandle bHandle = ruleManager.readRule("javatestrule",
 				new BytesHandle().withFormat(Format.JSON));
 		assertEquals(
-				"{\"rule\":{\"name\":\"javatestrule\", \"description\":\"rule to demonstrate REST alerting\", \"search\":{\"qtext\":[\"favorited:true\"], \"options\":{\"constraint\":[{\"name\":\"favorited\", \"value\":{\"element\":{\"ns\":\"\", \"name\":\"favorited\"}}}]}}, \"rule-metadata\":null}}",
+				"{\"rule\":{\"name\":\"javatestrule\", \"description\":\"rule to demonstrate REST alerting\", \"search\":{\"qtext\":[\"favorited:true\"], \"options\":{\"constraint\":[{\"name\":\"favorited\", \"value\":{\"element\":{\"ns\":\"\", \"name\":\"favorited\"}}}]}}, \"rule-metadata\":null}}\n",
 				new String(bHandle.get()));
 
 		ruleManager.delete("javatestrule");
diff --git a/src/test/java/com/marklogic/client/test/BulkReadWriteTest.java b/src/test/java/com/marklogic/client/test/BulkReadWriteTest.java
index 3262e60e1..f007eec35 100644
--- a/src/test/java/com/marklogic/client/test/BulkReadWriteTest.java
+++ b/src/test/java/com/marklogic/client/test/BulkReadWriteTest.java
@@ -19,6 +19,7 @@
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.FileHandler;
 import java.util.logging.Handler;
 import java.util.logging.Logger;
@@ -26,7 +27,6 @@
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.XmlRootElement;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -38,8 +38,8 @@
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.marklogic.client.DatabaseClientFactory;
 import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.DocumentManager.Metadata;
 import com.marklogic.client.document.DocumentPage;
 import com.marklogic.client.document.DocumentRecord;
 import com.marklogic.client.document.DocumentWriteSet;
@@ -61,11 +61,11 @@
  **/
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class BulkReadWriteTest {
-    private static int BATCH_SIZE = 100;
-    private static String DIRECTORY = "/cities/";
-    private static String COUNTRIES_FILE = "countryInfo.txt";
-    private static String CITIES_FILE = "cities_above_300K.txt";
-    private static int RECORDS_EXPECTED = 1363;
+    private static final int BATCH_SIZE = 100;
+    static final String DIRECTORY = "/cities/";
+    private static final String COUNTRIES_FILE = "countryInfo.txt";
+    private static final String CITIES_FILE = "cities_above_300K.txt";
+    static final int RECORDS_EXPECTED = 1363;
     private static JAXBContext context = null;
 
     @BeforeClass
@@ -73,7 +73,6 @@ public static void beforeClass() throws JAXBException {
         Common.connect();
         context = JAXBContext.newInstance(City.class);
         //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
-        //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");    
     }
     @AfterClass
     public static void afterClass() {
@@ -81,204 +80,44 @@ public static void afterClass() {
         Common.release();
     }
 
-    static public class Country {
-        private String name, continent, currencyCode, currencyName, isoCode;
-
-        public String getIsoCode() {
-            return isoCode;
-        }
-
-        public Country setIsoCode(String isoCode) {
-            this.isoCode = isoCode;
-            return this;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Country setName(String name) {
-            this.name = name;
-            return this;
-        }
-
-        public String getContinent() {
-            return continent;
-        }
-
-        public Country setContinent(String continent) {
-            this.continent = continent;
-            return this;
-        }
-
-        public String getCurrencyCode() {
-            return currencyCode;
-        }
-
-        public Country setCurrencyCode(String currencyCode) {
-            this.currencyCode = currencyCode;
-            return this;
-        }
-
-        public String getCurrencyName() {
-            return currencyName;
-        }
-
-        public Country setCurrencyName(String currencyName) {
-            this.currencyName = currencyName;
-            return this;
-        }
+    interface CityWriter {
+        public void addCity(City city);
+        public void finishBatch();
+        public void setNumRecords(int numWritten);
     }
 
-    @XmlRootElement
-    static public class City {
-        private int geoNameId;
-        private String name;
-        private String asciiName;
-        private String[] alternateNames;
-        private double latitude;
-        private double longitude;
-        private String countryIsoCode;
-        private String countryName;
-        private String continent;
-        private String currencyCode;
-        private String currencyName;
-        private long population;
-        private int elevation;
-
-        public int getGeoNameId() {
-            return geoNameId;
-        }
-
-        public City setGeoNameId(int geoNameId) {
-            this.geoNameId = geoNameId;
-            return this;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public City setName(String name) {
-            this.name = name;
-            return this;
-        }
-
-        public String getAsciiName() {
-            return asciiName;
-        }
-
-        public City setAsciiName(String asciiName) {
-            this.asciiName = asciiName;
-            return this;
-        }
-
-        public String[] getAlternateNames() {
-            return alternateNames;
-        }
-
-        public City setAlternateNames(String[] alternateNames) {
-            this.alternateNames = alternateNames;
-            return this;
-        }
-
-        public double getLatitude() {
-            return latitude;
-        }
-
-        public City setLatitude(double latitude) {
-            this.latitude = latitude;
-            return this;
-        }
-
-        public double getLongitude() {
-            return longitude;
-        }
-
-        public City setLongitude(double longitude) {
-            this.longitude = longitude;
-            return this;
-        }
-
-        public String getCountryIsoCode() {
-            return countryIsoCode;
-        }
-
-        public City setCountryIsoCode(String countryIsoCode) {
-            this.countryIsoCode = countryIsoCode;
-            return this;
-        }
+    private class BulkCityWriter implements CityWriter {
+        private XMLDocumentManager docMgr = Common.client.newXMLDocumentManager();
+        private JAXBContext context;
+        private DocumentWriteSet writeSet = docMgr.newWriteSet();
 
-        public String getCountryName() {
-            return countryName;
+        BulkCityWriter() throws JAXBException {
+            context = JAXBContext.newInstance(City.class);
         }
 
-        public City setCountryName(String countryName) {
-            this.countryName = countryName;
-            return this;
-        }
-
-        public String getContinent() {
-            return continent;
-        }
-
-        public City setContinent(String continent) {
-            this.continent = continent;
-            return this;
-        }
-
-        public String getCurrencyCode() {
-            return currencyCode;
-        }
-
-        public City setCurrencyCode(String currencyCode) {
-            this.currencyCode = currencyCode;
-            return this;
-        }
-
-        public String getCurrencyName() {
-            return currencyName;
-        }
-
-        public City setCurrencyName(String currencyName) {
-            this.currencyName = currencyName;
-            return this;
-        }
-
-        public long getPopulation() {
-            return population;
-        }
-
-        public City setPopulation(long population) {
-            this.population = population;
-            return this;
+        public void addCity(City city) {
+            JAXBHandle handle = new JAXBHandle(context);
+            // set the handle to the POJO instance
+            handle.set(city);
+            writeSet.add( DIRECTORY + city.getGeoNameId() + ".xml", handle );
         }
 
-        public int getElevation() {
-            return elevation;
+        public void finishBatch() {
+            docMgr.write(writeSet);
+            writeSet = docMgr.newWriteSet();
         }
 
-        public City setElevation(int elevation) {
-            this.elevation = elevation;
-            return this;
+        public void setNumRecords(int numWritten) {
+            assertEquals("Number of records not expected", RECORDS_EXPECTED, numWritten);
         }
     }
 
-    @Test
-    public void testBulkLoad() throws IOException, JAXBException {
-        // register the POJO class
-        DatabaseClientFactory.getHandleRegistry().register(
-            JAXBHandle.newFactory(City.class)
-        );
-        XMLDocumentManager docMgr = Common.client.newXMLDocumentManager();
-
-        JAXBContext context = JAXBContext.newInstance(City.class);
-
+    static void loadCities(CityWriter cityWriter) throws Exception {
         // load all the countries into a HashMap (this isn't the big data set)
         // we'll attach country info to each city (that's the big data set)
         Map countries = new HashMap();
-        System.out.println("1:" + BulkReadWriteTest.class.getClassLoader().getResourceAsStream(COUNTRIES_FILE));
-        BufferedReader countryReader = new BufferedReader(Common.testFileToReader(COUNTRIES_FILE));
+        System.out.println("Reading countries:" + BulkReadWriteTest.class.getClassLoader().getResourceAsStream(COUNTRIES_FILE));
+        BufferedReader countryReader = new BufferedReader(Common.testFileToReader(COUNTRIES_FILE, "UTF-8"));
         String line;
         while ((line = countryReader.readLine()) != null ) {
             addCountry(line, countries);
@@ -286,39 +125,38 @@ public void testBulkLoad() throws IOException, JAXBException {
         countryReader.close();
 
         // write batches of cities combined with their country info
-        DocumentWriteSet writeSet = docMgr.newWriteSet();
-        System.out.println(BulkReadWriteTest.class.getClassLoader().getResourceAsStream(CITIES_FILE));
-        BufferedReader cityReader = new BufferedReader(Common.testFileToReader(CITIES_FILE));
+        System.out.println("Reading cities:" + BulkReadWriteTest.class.getClassLoader().getResource(CITIES_FILE));
+        BufferedReader cityReader = new BufferedReader(Common.testFileToReader(CITIES_FILE, "UTF-8"));
         line = null;
-        long numWritten = 0;
+        int numWritten = 0;
         while ((line = cityReader.readLine()) != null ) {
 
             // instantiate the POJO for this city
             City city = newCity(line, countries);
-
-            // set the handle to the POJO instance
-            JAXBHandle handle = new JAXBHandle(context);
-            handle.set(city);
-            writeSet.add( DIRECTORY + city.getGeoNameId() + ".xml", handle );
+            // let the implementation handle writing the city
+            cityWriter.addCity(city);
 
             // when we have a full batch, write it out
             if ( ++numWritten % BATCH_SIZE == 0 ) {
-                docMgr.write(writeSet);
-                writeSet = docMgr.newWriteSet();
+                cityWriter.finishBatch();
             }
         }
         // if there are any leftovers, let's write this last batch
         if ( numWritten % BATCH_SIZE > 0 ) {
-            docMgr.write(writeSet);
+            cityWriter.finishBatch();
         }
+        cityWriter.setNumRecords(numWritten);
         cityReader.close();
+    }
         
 
-        assertEquals("Number of records not expected", numWritten, RECORDS_EXPECTED);
+    @Test
+    public void testA_BulkLoad() throws IOException, Exception {
+        loadCities(new BulkCityWriter());
     }
 
     @Test
-    public void testBulkRead() {
+    public void testB_BulkRead() {
         XMLDocumentManager docMgr = Common.client.newXMLDocumentManager();
 
         DocumentPage page = docMgr.read(DIRECTORY + "1016670.xml", DIRECTORY + "108410.xml", DIRECTORY + "1205733.xml");
@@ -332,7 +170,7 @@ public void testBulkRead() {
     }
 
     @Test
-    public void testBulkSearch() {
+    public void testC_BulkSearch() {
         XMLDocumentManager docMgr = Common.client.newXMLDocumentManager();
 
         SearchHandle searchHandle = new SearchHandle();
@@ -351,7 +189,7 @@ public void testBulkSearch() {
 
     //public void testMixedLoad() {
     @Test
-    public void testJsonLoad() {
+    public void testD_JsonLoad() {
         JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
 
         StringHandle doc1 =
@@ -361,7 +199,7 @@ public void testJsonLoad() {
             new StringHandle("{\"animal\": \"cat\", \"says\": \"meow\"}").withFormat(Format.JSON);
 
         StringHandle doc2Metadata =
-            new StringHandle("{\"quality\" : 2.0}").withFormat(Format.JSON);
+            new StringHandle("{\"quality\" : 2}").withFormat(Format.JSON);
 
         DocumentWriteSet writeSet = docMgr.newWriteSet();
         writeSet.add("doc1.json", doc1);
@@ -380,7 +218,7 @@ public void testJsonLoad() {
         assertEquals("Failed to read document 2", "cat", content2.get().get("animal").textValue());
     }
 
-    public void validateRecord(DocumentRecord record) {
+    private void validateRecord(DocumentRecord record) {
         JAXBHandle handle = new JAXBHandle(context);
         assertNotNull("DocumentRecord should never be null", record);
         assertNotNull("Document uri should never be null", record.getUri());
@@ -392,19 +230,23 @@ public void validateRecord(DocumentRecord record) {
         */
         if ( record.getUri().equals(DIRECTORY + "1205733.xml") ) {
             City chittagong = record.getContent(handle).get();
-            assertEquals("City name doesn't match", "Chittagong", chittagong.getName());
-            assertEquals("City latitude doesn't match", 22.3384, chittagong.getLatitude(), 0);
-            assertEquals("City longitude doesn't match", 91.83168, chittagong.getLongitude(), 0);
-            assertEquals("City population doesn't match", 3920222, chittagong.getPopulation());
-            assertEquals("City elevation doesn't match", 15, chittagong.getElevation());
-            assertEquals("Currency code doesn't match", "BDT", chittagong.getCurrencyCode());
-            assertEquals("Currency name doesn't match", "Taka", chittagong.getCurrencyName());
+            validateChittagong(chittagong);
         }
     }
 
+    public static void validateChittagong(City chittagong) {
+        assertEquals("City name doesn't match", "Chittagong", chittagong.getName());
+        assertEquals("City latitude doesn't match", 22.3384, chittagong.getLatitude(), 0);
+        assertEquals("City longitude doesn't match", 91.83168, chittagong.getLongitude(), 0);
+        assertEquals("City population doesn't match", 3920222, chittagong.getPopulation());
+        assertEquals("City elevation doesn't match", 15, chittagong.getElevation());
+        assertEquals("Currency code doesn't match", "BDT", chittagong.getCurrencyCode());
+        assertEquals("Currency name doesn't match", "Taka", chittagong.getCurrencyName());
+    }
+
     @Test
-    public void testTextLoad() {
-        String docId[] = {"/foo/test/myFoo1.xml","/foo/test/myFoo2.xml","/foo/test/myFoo3.xml"};
+    public void testE_TextLoad() {
+        String docId[] = {"/foo/test/myFoo1.txt","/foo/test/myFoo2.txt","/foo/test/myFoo3.txt"};
         TextDocumentManager docMgr = Common.client.newTextDocumentManager();
         DocumentWriteSet writeset =docMgr.newWriteSet();
 
@@ -422,6 +264,113 @@ public void testTextLoad() {
         docMgr.delete(docId[2]);
     }
 
+    @Test
+    public void testF_DefaultMetadata() {
+        // Synthesize input content
+        StringHandle doc1 = new StringHandle(
+                "{\"number\": 1}").withFormat(Format.JSON);
+        StringHandle doc2 = new StringHandle(
+                "{\"number\": 2}").withFormat(Format.JSON);
+        StringHandle doc3 = new StringHandle(
+                "{\"number\": 3}").withFormat(Format.JSON);
+        StringHandle doc4 = new StringHandle(
+                "{\"number\": 4}").withFormat(Format.JSON);
+        StringHandle doc5 = new StringHandle(
+                "{\"number\": 5}").withFormat(Format.JSON);
+        StringHandle doc6 = new StringHandle(
+                "{\"number\": 6}").withFormat(Format.JSON);
+        StringHandle doc7 = new StringHandle(
+                "{\"number\": 7}").withFormat(Format.JSON);
+        StringHandle doc8 = new StringHandle(
+                "{\"number\": 8}").withFormat(Format.JSON);
+
+        // Synthesize input metadata
+        DocumentMetadataHandle defaultMetadata1 = 
+                new DocumentMetadataHandle().withQuality(1);
+        DocumentMetadataHandle defaultMetadata2 = 
+                new DocumentMetadataHandle().withQuality(2);
+        DocumentMetadataHandle docSpecificMetadata = 
+                new DocumentMetadataHandle().withCollections("myCollection");
+
+        // Create and build up the batch
+        JSONDocumentManager jdm = Common.client.newJSONDocumentManager();
+        DocumentWriteSet batch = jdm.newWriteSet();
+
+        // use system default metadata
+        batch.add("doc1.json", doc1);       // system default metadata
+
+        // using batch default metadata
+        batch.addDefault(defaultMetadata1);  
+        batch.add("doc2.json", doc2);       // batch default metadata
+        batch.add("doc3.json", docSpecificMetadata, doc3);
+        batch.add("doc4.json", doc4);       // batch default metadata
+
+        // replace batch default metadata with new metadata
+        batch.addDefault(defaultMetadata2); 
+        batch.add("doc5.json", doc5);       // batch default 
+
+        // replace default metadata with blank metadata (back to system defaults)
+        batch.disableDefault(); 
+        batch.add("doc6.json", doc6);       // system default metadata
+        batch.addDefault(defaultMetadata1); 
+        batch.add("doc7.json", doc7);       // batch default metadata
+        batch.disableDefault(); 
+        batch.add("doc8.json", doc8);       // system default metadata
+
+        // Execute the write operation
+        jdm.write(batch);
+
+        // need the "synthetic response" format to be XML
+        jdm.setResponseFormat(Format.XML);
+        // Check the results
+        assertEquals("Doc1 should have the system default quality of 0", 0, 
+            jdm.readMetadata("doc1.json", new DocumentMetadataHandle()).getQuality());
+        assertEquals("Doc2 should use the first batch default metadata, with quality 1", defaultMetadata1.getQuality(), 
+                jdm.readMetadata("doc2.json", new DocumentMetadataHandle()).getQuality());
+
+        DocumentMetadataHandle doc3Metadata =  
+                jdm.readMetadata("doc3.json", new DocumentMetadataHandle());
+        assertEquals("Doc3 should have the system default document quality (0) because quality " +
+            "was not included in the document-specific metadata.", 0, doc3Metadata.getQuality());
+        Set collections = doc3Metadata.getCollections();
+        assertEquals("Doc3 should be in exactly one collection from the document-specific metadata.", 1, collections.size());
+        assertEquals("Doc3 should be in the collection \"myCollection\", from the document-specific metadata.",
+            "myCollection", collections.iterator().next());
+
+        // let's check getting content with just quality in the metadata 
+        jdm.setMetadataCategories(Metadata.QUALITY);
+        DocumentPage documents = jdm.read("doc4.json", "doc5.json");
+
+        for ( DocumentRecord doc: documents ) {
+            DocumentMetadataHandle metadata = doc.getMetadata(new DocumentMetadataHandle());
+            StringHandle content = doc.getContent(new StringHandle());
+            if ( "doc4.json".equals(doc.getUri()) ) {
+                assertEquals("Doc4 should also use the 1st batch default metadata, with quality 1", 1,
+                    metadata.getQuality());
+                assertTrue("Doc 4 contents are wrong", content.get().matches("\\{\"number\": ?4\\}"));
+            } else if ( "doc5.json".equals(doc.getUri()) ) {
+                assertEquals("Doc5 should use the 2nd batch default metadata, with quality 2", 2,
+                    metadata.getQuality());
+                assertTrue("Doc 5 contents are wrong", content.get().matches("\\{\"number\": ?5\\}"));
+            }
+        }
+
+        // now try with just metadata
+        documents = jdm.readMetadata("doc6.json", "doc7.json", "doc8.json");
+        for ( DocumentRecord doc: documents ) {
+            DocumentMetadataHandle metadata = doc.getMetadata(new DocumentMetadataHandle());
+            if ( "doc6.json".equals(doc.getUri()) ) {
+                assertEquals("Doc 6 should have the system default quality of 0", 0,
+                    metadata.getQuality());
+            } else if ( "doc7.json".equals(doc.getUri()) ) {
+                assertEquals("Doc7 should also use the 1st batch default metadata, with quality 1", 1,
+                    metadata.getQuality());
+            } else if ( "doc8.json".equals(doc.getUri()) ) {
+                assertEquals("Doc 8 should have the system default quality of 0", 0,
+                    metadata.getQuality());
+            }
+        }
+    }
 
 
     private static void addCountry(String line, Map countries) {
@@ -440,11 +389,11 @@ private static void addCountry(String line, Map countries) {
         );
     }
 
-    private static Country getCountry(String isoCode, Map countries) {
+    public static Country getCountry(String isoCode, Map countries) {
         return countries.get(isoCode);
     }
 
-    private static City newCity(String line, Map countries) {
+    public static City newCity(String line, Map countries) {
         String[] fields = line.split("	");
         try {
             City city = new City()
@@ -454,6 +403,9 @@ private static City newCity(String line, Map countries) {
               .setAlternateNames( fields[3].split(",") );
             if ( !fields[4].equals("") ) city.setLatitude( Double.parseDouble(fields[4]) );
             if ( !fields[5].equals("") ) city.setLongitude( Double.parseDouble(fields[5]) );
+            if ( !fields[4].equals("") && !fields[5].equals("") ) {
+                city.setLatLong( fields[4] + " " + fields[5] );
+            }
             if ( !fields[14].equals("") ) city.setPopulation( Long.parseLong(fields[14]) );
             if ( !fields[16].equals("") ) city.setElevation( Integer.parseInt(fields[16]) );
             if ( !fields[8].equals("") ) {
@@ -472,13 +424,14 @@ private static City newCity(String line, Map countries) {
         }
     }
 
-    private static void cleanUp() {
+    public static void cleanUp() {
         QueryManager queryMgr = Common.client.newQueryManager();
         DeleteQueryDefinition deleteQuery = queryMgr.newDeleteDefinition();
         deleteQuery.setDirectory("/cities/");
         queryMgr.delete(deleteQuery);
         JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
-        docMgr.delete("doc1.json");
-        docMgr.delete("doc2.json");
+        for ( int i=1; i <= 8; i++ ) {
+            docMgr.delete("doc" + i + ".json");
+        }
     }
 }
diff --git a/src/test/java/com/marklogic/client/test/City.java b/src/test/java/com/marklogic/client/test/City.java
new file mode 100644
index 000000000..f0d2e8d3e
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/City.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.marklogic.client.pojo.annotation.Id;
+
+@XmlRootElement
+public class City {
+    private int geoNameId;
+    private String name;
+    private String asciiName;
+    private String[] alternateNames;
+    private double latitude;
+    private double longitude;
+    private String latLong;
+    private String countryIsoCode;
+    private String countryName;
+    private String continent;
+    private String currencyCode;
+    private String currencyName;
+    private long population;
+    private int elevation;
+    private Country country;
+
+    @Id
+    public int getGeoNameId() {
+        return geoNameId;
+    }
+
+    public City setGeoNameId(int geoNameId) {
+        this.geoNameId = geoNameId;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public City setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public String getAsciiName() {
+        return asciiName;
+    }
+
+    public City setAsciiName(String asciiName) {
+        this.asciiName = asciiName;
+        return this;
+    }
+
+    public String[] getAlternateNames() {
+        return alternateNames;
+    }
+
+    public City setAlternateNames(String[] alternateNames) {
+        this.alternateNames = alternateNames;
+        return this;
+    }
+
+    public double getLatitude() {
+        return latitude;
+    }
+
+    public City setLatitude(double latitude) {
+        this.latitude = latitude;
+        return this;
+    }
+
+    public double getLongitude() {
+        return longitude;
+    }
+
+    public City setLongitude(double longitude) {
+        this.longitude = longitude;
+        return this;
+    }
+
+    public String getLatLong() {
+        return latLong;
+    }
+
+    public City setLatLong(String latLong) {
+        this.latLong = latLong;
+        return this;
+    }
+
+    public String getCountryIsoCode() {
+        return countryIsoCode;
+    }
+
+    public City setCountryIsoCode(String countryIsoCode) {
+        this.countryIsoCode = countryIsoCode;
+        return this;
+    }
+
+    public String getCountryName() {
+        return countryName;
+    }
+
+    public City setCountryName(String countryName) {
+        this.countryName = countryName;
+        return this;
+    }
+
+    public String getContinent() {
+        return continent;
+    }
+
+    public City setContinent(String continent) {
+        this.continent = continent;
+        return this;
+    }
+
+    public String getCurrencyCode() {
+        return currencyCode;
+    }
+
+    public City setCurrencyCode(String currencyCode) {
+        this.currencyCode = currencyCode;
+        return this;
+    }
+
+    public String getCurrencyName() {
+        return currencyName;
+    }
+
+    public City setCurrencyName(String currencyName) {
+        this.currencyName = currencyName;
+        return this;
+    }
+
+    public long getPopulation() {
+        return population;
+    }
+
+    public City setPopulation(long population) {
+        this.population = population;
+        return this;
+    }
+
+    public int getElevation() {
+        return elevation;
+    }
+
+    public City setElevation(int elevation) {
+        this.elevation = elevation;
+        return this;
+    }
+
+    public Country getCountry() {
+        return country;
+    }
+
+    public City setCountry(Country country) {
+        this.country = country;
+        return this;
+    }
+}
diff --git a/src/test/java/com/marklogic/client/test/ConditionalDocumentTest.java b/src/test/java/com/marklogic/client/test/ConditionalDocumentTest.java
index da8a501a0..4021aa4cc 100644
--- a/src/test/java/com/marklogic/client/test/ConditionalDocumentTest.java
+++ b/src/test/java/com/marklogic/client/test/ConditionalDocumentTest.java
@@ -46,6 +46,7 @@ public class ConditionalDocumentTest {
 	@BeforeClass
 	public static void beforeClass()
 	throws FailedRequestException, ForbiddenUserException, ResourceNotFoundException, ResourceNotResendableException {
+		//System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
 		Common.connectAdmin();
 		serverConfig = Common.client.newServerConfigManager();
 		serverConfig.readConfiguration();
@@ -97,7 +98,7 @@ public void testConditional() throws SAXException, IOException,
 		assertTrue("Write with bad version succeeded", ex != null);
 		assertTrue("Write with bad version had wrong error", statusCode == 412);
 		assertTrue("Write with no version had misleading message", 
-				ex.getMessage().contains("Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION: (err:FOER0000) Content version mismatch:  uri: /test/conditional1.xml"));
+				ex.getMessage().contains("Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION: (err:FOER0000) Content version mismatch:  uri /test/conditional1.xml doesn't match if-match: 11111"));
 
 
 		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
@@ -148,7 +149,7 @@ public void testConditional() throws SAXException, IOException,
 		assertTrue("Overwrite with bad version succeeded", ex != null);
 		assertTrue("Write with bad version had wrong error", statusCode == 412);
 		assertTrue("Write with no version had misleading message", 
-				ex.getMessage().contains("Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION: (err:FOER0000) Content version mismatch:  uri: /test/conditional1.xml version:"));
+				ex.getMessage().contains("Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION: (err:FOER0000) Content version mismatch:  uri /test/conditional1.xml has current version"));
 
 		desc.setVersion(goodVersion);
 		docMgr.write(desc, contentHandle);
diff --git a/src/test/java/com/marklogic/client/test/Country.java b/src/test/java/com/marklogic/client/test/Country.java
new file mode 100644
index 000000000..8e7410c1d
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/Country.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+public class Country {
+    private String name, continent, currencyCode, currencyName, isoCode;
+
+    public String getIsoCode() {
+        return isoCode;
+    }
+
+    public Country setIsoCode(String isoCode) {
+        this.isoCode = isoCode;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Country setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public String getContinent() {
+        return continent;
+    }
+
+    public Country setContinent(String continent) {
+        this.continent = continent;
+        return this;
+    }
+
+    public String getCurrencyCode() {
+        return currencyCode;
+    }
+
+    public Country setCurrencyCode(String currencyCode) {
+        this.currencyCode = currencyCode;
+        return this;
+    }
+
+    public String getCurrencyName() {
+        return currencyName;
+    }
+
+    public Country setCurrencyName(String currencyName) {
+        this.currencyName = currencyName;
+        return this;
+    }
+}
diff --git a/src/test/java/com/marklogic/client/test/ExtensionLibrariesTest.java b/src/test/java/com/marklogic/client/test/ExtensionLibrariesTest.java
index de756de2f..bb7b94993 100644
--- a/src/test/java/com/marklogic/client/test/ExtensionLibrariesTest.java
+++ b/src/test/java/com/marklogic/client/test/ExtensionLibrariesTest.java
@@ -24,6 +24,7 @@ public void testXQueryModuleCRUD()
 	throws ResourceNotFoundException, ResourceNotResendableException, ForbiddenUserException, FailedRequestException {
 
 		Common.connectAdmin();
+		//System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
 
 		// get a manager
 		ExtensionLibrariesManager libsMgr = Common.client
diff --git a/src/test/java/com/marklogic/client/test/GenericDocumentTest.java b/src/test/java/com/marklogic/client/test/GenericDocumentTest.java
index 0332c82c7..6fda6c330 100644
--- a/src/test/java/com/marklogic/client/test/GenericDocumentTest.java
+++ b/src/test/java/com/marklogic/client/test/GenericDocumentTest.java
@@ -420,4 +420,7 @@ public void testPatch() throws IOException, XpathException, SAXException {
 
 		docMgr.delete(docId);
 	}
+	
+	
 }
+
diff --git a/src/test/java/com/marklogic/client/test/InvalidUserTest.java b/src/test/java/com/marklogic/client/test/InvalidUserTest.java
index 4b4afdb6f..5585cdcb7 100755
--- a/src/test/java/com/marklogic/client/test/InvalidUserTest.java
+++ b/src/test/java/com/marklogic/client/test/InvalidUserTest.java
@@ -40,14 +40,12 @@ public void testInvalidUserAuth() {
 
         String docId = "/example/text.txt";
         TextDocumentManager docMgr = client.newTextDocumentManager();
-        // write doc
-        try
-        {
-            // make use of the client connection
+        try {
+            // make use of the client connection so we get an auth error
             StringHandle handle = new StringHandle();
             handle.set("A simple text document");
             docMgr.write(docId, handle);
-            assertEquals(expectedException, exception);
+            // the next line will only run if write doesn't throw an exception
             docMgr.delete(docId);
         }
         catch (Exception e) {
@@ -55,6 +53,7 @@ public void testInvalidUserAuth() {
         } finally {
             client.release();
         }
+        assertEquals(expectedException, exception);
 
     }
 }
diff --git a/src/test/java/com/marklogic/client/test/JSONDocumentTest.java b/src/test/java/com/marklogic/client/test/JSONDocumentTest.java
index 25ef0453b..e92f9f54e 100644
--- a/src/test/java/com/marklogic/client/test/JSONDocumentTest.java
+++ b/src/test/java/com/marklogic/client/test/JSONDocumentTest.java
@@ -15,42 +15,65 @@
  */
 package com.marklogic.client.test;
 
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.Reader;
+import java.nio.charset.Charset;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
+import org.custommonkey.xmlunit.exceptions.XpathException;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.w3c.dom.Document;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
 
-import com.marklogic.client.io.Format;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.document.DocumentManager.Metadata;
 import com.marklogic.client.document.DocumentMetadataPatchBuilder.Cardinality;
 import com.marklogic.client.document.DocumentPatchBuilder;
+import com.marklogic.client.document.DocumentPatchBuilder.PathLanguage;
 import com.marklogic.client.document.DocumentPatchBuilder.Position;
 import com.marklogic.client.document.JSONDocumentManager;
 import com.marklogic.client.io.BytesHandle;
-import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
 import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
 import com.marklogic.client.io.InputStreamHandle;
 import com.marklogic.client.io.ReaderHandle;
 import com.marklogic.client.io.StringHandle;
 import com.marklogic.client.io.marker.DocumentPatchHandle;
 
 public class JSONDocumentTest {
+
+	final static String metadata = 
+			  "  {\"collections\":\n"
+			+ "    [\"collection1\",\n" 
+			+ "    \"collection2\",\n"
+			+ "    \"collection4before\"],\n" 
+			+ "   \"permissions\":[\n"
+			+ "     {\"role-name\":\"app-user\",\n"
+			+ "      \"capabilities\":[\"update\",\"read\"]}],\n"
+			+ "   \"properties\":[\n" 
+			+ "    {\"first\":\"value one\",\n"
+			+ "     \"second\":2}]," 
+			+ "  \"quality\":3}\n";
+
+	static final private Logger logger = LoggerFactory
+			.getLogger(JSONDocumentTest.class);
+
 	@BeforeClass
 	public static void beforeClass() {
 		Common.connect();
 	}
+
 	@AfterClass
 	public static void afterClass() {
 		Common.release();
@@ -67,77 +90,207 @@ public void testReadWrite() throws IOException {
 		docMgr.write(docId, new StringHandle().with(content));
 
 		String docText = docMgr.read(docId, new StringHandle()).get();
-		assertNotNull("Read null string for JSON content",docText);
+		assertNotNull("Read null string for JSON content", docText);
 		JsonNode readNode = mapper.readTree(docText);
-		assertTrue("Failed to read JSON document as String", sourceNode.equals(readNode));
-		
+		assertTrue("Failed to read JSON document as String",
+				sourceNode.equals(readNode));
+
 		BytesHandle bytesHandle = new BytesHandle();
 		docMgr.read(docId, bytesHandle);
 		readNode = mapper.readTree(bytesHandle.get());
-		assertTrue("JSON document mismatch reading bytes", sourceNode.equals(readNode));
+		assertTrue("JSON document mismatch reading bytes",
+				sourceNode.equals(readNode));
 
 		InputStreamHandle inputStreamHandle = new InputStreamHandle();
 		docMgr.read(docId, inputStreamHandle);
 		readNode = mapper.readTree(inputStreamHandle.get());
-		assertTrue("JSON document mismatch reading input stream", sourceNode.equals(readNode));
+		assertTrue("JSON document mismatch reading input stream",
+				sourceNode.equals(readNode));
 
 		Reader reader = docMgr.read(docId, new ReaderHandle()).get();
 		readNode = mapper.readTree(reader);
-		assertTrue("JSON document mismatch with reader", sourceNode.equals(readNode));
+		assertTrue("JSON document mismatch with reader",
+				sourceNode.equals(readNode));
 
 		File file = docMgr.read(docId, new FileHandle()).get();
 		readNode = mapper.readTree(file);
-		assertTrue("JSON document mismatch with file", sourceNode.equals(readNode));
+		assertTrue("JSON document mismatch with file",
+				sourceNode.equals(readNode));
 	}
 
 	@Test
-	public void testPatch() throws IOException {
+	public void testJsonPathPatch() throws IOException {
 		String docId = "/test/testWrite1.json";
 		ObjectMapper mapper = new ObjectMapper();
 		ObjectNode sourceNode = makeContent(mapper);
 		String content = mapper.writeValueAsString(sourceNode);
-
 		JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
 		docMgr.write(docId, new StringHandle().with(content));
 
-		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder().pathLanguage(
+				PathLanguage.JSONPATH);
 
-		patchBldr.replaceValue("$.stringKey", Cardinality.ONE, "replaced value");
+		patchBldr
+				.replaceValue("$.stringKey", Cardinality.ONE, "replaced value");
 
-		patchBldr.delete("$.numberKey");
+		patchBldr.replaceApply("$.numberKey", patchBldr.call().add(2));
 
 		ObjectNode fragmentNode = mapper.createObjectNode();
-		fragmentNode.put("replacedChildKey","replaced object value");
+		fragmentNode.put("replacedChildKey", "replaced object value");
 		String fragment = mapper.writeValueAsString(fragmentNode);
 		patchBldr.replaceFragment("$.objectKey.childObjectKey", fragment);
 
 		fragmentNode = mapper.createObjectNode();
-		fragmentNode.put("insertedKey",9);
+		fragmentNode.put("insertedKey", 9);
 		fragment = mapper.writeValueAsString(fragmentNode);
 		patchBldr.insertFragment("$.arrayKey", Position.BEFORE, fragment);
 
-		patchBldr.replaceApply("$.arrayKey.[*][?(@=\"3\")]", patchBldr.call().add(2));
+		// patchBldr.delete("$.arrayKey.[*][?(@.string=\"3\")]");
 
 		fragmentNode = mapper.createObjectNode();
-		fragmentNode.put("appendedKey","appended item");
+		fragmentNode.put("appendedKey", "appended item");
 		fragment = mapper.writeValueAsString(fragmentNode);
-		patchBldr.insertFragment(
-				"$.arrayKey", Position.LAST_CHILD, Cardinality.ZERO_OR_ONE, fragment
-				);
+		patchBldr.insertFragment("$.arrayKey", Position.LAST_CHILD,
+				Cardinality.ZERO_OR_ONE, fragment);
+
+		DocumentPatchHandle patchHandle = patchBldr.pathLanguage(
+				PathLanguage.JSONPATH).build();
+
+		logger.debug("Patch:" + patchHandle.toString());
+		docMgr.patch(docId, patchHandle);
+
+		ObjectNode expectedNode = mapper.createObjectNode();
+		expectedNode.put("stringKey", "replaced value");
+		expectedNode.put("numberKey", 9);
+		ObjectNode childNode = mapper.createObjectNode();
+		childNode.put("replacedChildKey", "replaced object value");
+		expectedNode.put("objectKey", childNode);
+		expectedNode.put("insertedKey", 9);
+		ArrayNode childArray = mapper.createArrayNode();
+		childArray.add("item value");
+		childArray.add(3);
+		childNode = mapper.createObjectNode();
+		childNode.put("itemObjectKey", "item object value");
+		childArray.add(childNode);
+		childNode = mapper.createObjectNode();
+		childNode.put("appendedKey", "appended item");
+		childArray.add(childNode);
+		expectedNode.put("arrayKey", childArray);
+
+		String docText = docMgr.read(docId, new StringHandle()).get();
+		assertNotNull("Read null string for patched JSON content", docText);
+		
+		logger.debug("Before:" + content);
+		logger.debug("After:"+docText);
+		logger.debug("Expected:" + mapper.writeValueAsString(expectedNode));
+		
+		JsonNode readNode = mapper.readTree(docText);
+		assertTrue("Patched JSON document without expected result",
+				expectedNode.equals(readNode));
+
+	}
+	
+	@Test
+	public void testJSONPathMetadata() throws IOException, XpathException, SAXException {
+		String docId = "/test/testWrite1.json";
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode sourceNode = makeContent(mapper);
+		String content = mapper.writeValueAsString(sourceNode);
+
+		JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
+		
+		// add metadata patch here. This will be failing now.
+		docMgr.write(docId,
+				new BytesHandle(content.getBytes(Charset.forName("UTF-8")))
+						.withFormat(Format.JSON));
+
+		docMgr.setMetadataCategories(Metadata.ALL);
+
+		docMgr.writeMetadata(docId, new StringHandle().with(metadata).withFormat(Format.JSON));
+
+		DocumentPatchBuilder patchBldr =  docMgr.newPatchBuilder().pathLanguage(
+				PathLanguage.JSONPATH);
+
+		DocumentPatchHandle patchHandle = patchBldr
+				.pathLanguage(PathLanguage.JSONPATH)
+				.addCollection("collection3")
+				.replaceCollection("collection4before",
+						"collection4after")
+				.replacePermission("app-user", Capability.UPDATE)
+				.deleteProperty("first")
+				.replacePropertyApply("second", patchBldr.call().add(3))
+				.setQuality(4).build();
+
+		docMgr.patch(docId, patchHandle);
+
+		String metadata = docMgr.readMetadata(docId,
+				new StringHandle().withFormat(Format.XML)).get();
+
+		assertTrue("Could not read document metadata after write default",
+				metadata != null);
+
+		assertTrue("Could not read document metadata after write default", metadata != null);
+		assertXpathEvaluatesTo("4","count(/*[local-name()='metadata']/*[local-name()='collections']/*[local-name()='collection'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='collections']/*[local-name()='collection' and string(.)='collection4after'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='permissions']/*[local-name()='permission' and string(*[local-name()='role-name'])='app-user']/*[local-name()='capability'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='properties']/*[local-name()='first' or local-name()='second'])",metadata);
+		assertXpathEvaluatesTo("5","string(/*[local-name()='metadata']/*[local-name()='properties']/*[local-name()='second'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='quality' and string(.)='4'])",metadata);
+
+		docMgr.delete(docId);
+	}
+
+	@Test
+	public void testXPathPatch() throws IOException {
+		String docId = "/test/testWrite1.json";
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode sourceNode = makeContent(mapper);
+		String content = mapper.writeValueAsString(sourceNode);
+
+		JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
+		docMgr.write(docId, new StringHandle().with(content));
+
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+
+		patchBldr.replaceValue("/stringKey", Cardinality.ONE, "replaced value");
+
+		patchBldr.replaceApply("/numberKey", patchBldr.call().add(2));
+
+		ObjectNode fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("replacedChildKey", "replaced object value");
+		String fragment = mapper.writeValueAsString(fragmentNode);
+		patchBldr.replaceFragment("/objectKey/childObjectKey", fragment);
+
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("insertedKey", 9);
+		fragment = mapper.writeValueAsString(fragmentNode);
+		patchBldr.insertFragment("/node()/node('arrayKey')", Position.BEFORE,
+				fragment);
+
+		//patchBldr.replaceApply("/node()/arrayKey/node()[string(.) eq '3']",
+		//		patchBldr.call().add(2));
+
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("appendedKey", "appended item");
+		fragment = mapper.writeValueAsString(fragmentNode);
+		patchBldr.insertFragment("/node()/node('arrayKey')",
+				Position.LAST_CHILD, Cardinality.ZERO_OR_ONE, fragment);
 
 		DocumentPatchHandle patchHandle = patchBldr.build();
 
+		logger.debug("Sending patch " + patchBldr.build().toString());
 		docMgr.patch(docId, patchHandle);
 
 		ObjectNode expectedNode = mapper.createObjectNode();
 		expectedNode.put("stringKey", "replaced value");
+		expectedNode.put("numberKey",  9);
 		ObjectNode childNode = mapper.createObjectNode();
 		childNode.put("replacedChildKey", "replaced object value");
 		expectedNode.put("objectKey", childNode);
 		expectedNode.put("insertedKey", 9);
 		ArrayNode childArray = mapper.createArrayNode();
 		childArray.add("item value");
-		childArray.add(5);
+		childArray.add(3);
 		childNode = mapper.createObjectNode();
 		childNode.put("itemObjectKey", "item object value");
 		childArray.add(childNode);
@@ -147,9 +300,75 @@ public void testPatch() throws IOException {
 		expectedNode.put("arrayKey", childArray);
 
 		String docText = docMgr.read(docId, new StringHandle()).get();
-		assertNotNull("Read null string for patched JSON content",docText);
+		
+		assertNotNull("Read null string for patched JSON content", docText);
 		JsonNode readNode = mapper.readTree(docText);
-		assertTrue("Patched JSON document without expected result", expectedNode.equals(readNode));
+		
+
+		logger.debug("Before:" + content);
+		logger.debug("After:"+docText);
+		logger.debug("Expected:" + mapper.writeValueAsString(expectedNode));
+		
+		
+		assertTrue("Patched JSON document without expected result",
+				expectedNode.equals(readNode));
+
+		docMgr.delete(docId);
+	}
+	
+	@Test
+	public void testXPathJsonMetadata() throws IOException, XpathException, SAXException {
+		String docId = "/test/testWrite1.json";
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode sourceNode = makeContent(mapper);
+		String content = mapper.writeValueAsString(sourceNode);
+
+		JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
+		
+		// add metadata patch here. This will be failing now.
+		docMgr.write(docId,
+				new BytesHandle(content.getBytes(Charset.forName("UTF-8")))
+						.withFormat(Format.JSON));
+
+		docMgr.setMetadataCategories(Metadata.ALL);
+
+		docMgr.writeMetadata(docId, new StringHandle().with(metadata).withFormat(Format.JSON));
+
+		DocumentPatchBuilder patchBldr =  docMgr.newPatchBuilder().pathLanguage(
+				PathLanguage.JSONPATH);
+
+		DocumentPatchHandle patchHandle = patchBldr
+				.pathLanguage(PathLanguage.XPATH)
+				.addCollection("collection3")
+				.replaceCollection("collection4before",
+						"collection4after")
+				.replacePermission("app-user", Capability.UPDATE)
+				.deleteProperty("first")
+				.replacePropertyApply("second", patchBldr.call().add(3))
+				.setQuality(4).build();
+
+		logger.debug("Patch: "+ patchHandle.toString());
+		logger.debug("Before: "+ content);
+		docMgr.patch(docId, patchHandle);
+
+		String metadata = docMgr.readMetadata(docId,
+				new StringHandle().withFormat(Format.XML)).get();
+		String jsonMetadata = docMgr.readMetadata(docId,
+				new StringHandle().withFormat(Format.JSON)).get();
+
+		logger.debug("After: "+ jsonMetadata);
+
+		
+		assertTrue("Could not read document metadata after write default",
+				metadata != null);
+
+		assertTrue("Could not read document metadata after write default", metadata != null);
+		assertXpathEvaluatesTo("4","count(/*[local-name()='metadata']/*[local-name()='collections']/*[local-name()='collection'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='collections']/*[local-name()='collection' and string(.)='collection4after'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='permissions']/*[local-name()='permission' and string(*[local-name()='role-name'])='app-user']/*[local-name()='capability'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='properties']/*[local-name()='first' or local-name()='second'])",metadata);
+		assertXpathEvaluatesTo("5","string(/*[local-name()='metadata']/*[local-name()='properties']/*[local-name()='second'])",metadata);
+		assertXpathEvaluatesTo("1","count(/*[local-name()='metadata']/*[local-name()='quality' and string(.)='4'])",metadata);
 
 		docMgr.delete(docId);
 	}
diff --git a/src/test/java/com/marklogic/client/test/JacksonDatabindTest.java b/src/test/java/com/marklogic/client/test/JacksonDatabindTest.java
new file mode 100644
index 000000000..9b46d1504
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/JacksonDatabindTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.geonames.Toponym;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.JacksonDatabindHandle;
+import com.marklogic.client.query.DeleteQueryDefinition;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.test.Common;
+import com.marklogic.client.test.BulkReadWriteTest;
+import com.marklogic.client.test.City;
+import com.marklogic.client.test.BulkReadWriteTest.CityWriter;
+
+public class JacksonDatabindTest {
+    private static final String CITIES_FILE = "cities_above_300K.txt";
+    private static final int MAX_TO_WRITE = 10;
+    private static final String DIRECTORY = "/databindTest/";
+
+    @BeforeClass
+    public static void beforeClass() {
+        // demonstrate our ability to set advanced configuration on a mapper
+        ObjectMapper mapper = new ObjectMapper();
+        // in this case, we're saying wrap our serialization with the name of the pojo class
+        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT); 
+        // register a JacksonDatabindHandleFactory ready to marshall any City object to/from json
+        // this enables the writeAs method below
+        DatabaseClientFactory.getHandleRegistry().register(
+            JacksonDatabindHandle.newFactory(mapper, City.class)
+        );
+        Common.connect();
+        //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        cleanUp();
+        Common.release();
+    }
+
+    /** Here we're trying to keep it simple and demonstrate how you would use Jackson
+     * via JacksonDatabindHandle to do the most common-case databinding to serialize your 
+     * pojos to json.  JacksonDatabindHandle is created under the hood by the factory registered
+     * above in the beforeClass() method. To reuse existing code we're letting BulkReadWriteTest load 
+     * records from a csv file and populate our City pojos.  We just manage the 
+     * serialization and persistence logic.  We're also demonstrating how to register
+     * a factory so you can use the convenient writeAs method.
+     **/
+    public class JsonCityWriter implements CityWriter {
+        private int numCities = 0;
+        private JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
+
+        public void addCity(City city) {
+            if ( numCities >= MAX_TO_WRITE ) return;
+            docMgr.writeAs(DIRECTORY + "/jsonCities/" + city.getGeoNameId() + ".json", city);
+            numCities++;
+        }
+        public void finishBatch() {}
+        public void setNumRecords(int numRecords) {}
+    }
+    
+    @Test
+    public void testDatabind() throws Exception {
+        BulkReadWriteTest.loadCities(new JsonCityWriter());
+        // we can add assertions later, for now this test just serves as example code and 
+        // ensures no exceptions are thrown
+    }
+
+    /** We're going to demonstrate the versitility of Jackson by using and XmlMapper
+     * to serialize instead of the default JsonMapper to serialize to json.  Most 
+     * importantly, this points to the ability with JacksonHandle or JacksonDatabindHandle
+     * to bring your own mapper and all the power that comes with it.  We're also 
+     * demonstrating the Bulk read/write api this time to write the documents.
+     **/
+    public static class XmlCityWriter implements CityWriter {
+        private int numCities = 0;
+        private XMLDocumentManager docMgr = Common.client.newXMLDocumentManager();
+        private DocumentWriteSet writeSet = docMgr.newWriteSet();
+        private static XmlMapper mapper = new XmlMapper();
+        static {
+            mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
+            mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
+        }
+
+        public void addCity(City city) {
+            if ( numCities >= MAX_TO_WRITE ) return;
+            JacksonDatabindHandle handle = new JacksonDatabindHandle(city);
+            // NOTICE: We've set the mapper to an XmlMapper, showing the versitility of Jackson
+            handle.setMapper(mapper);
+            handle.setFormat(Format.XML);
+            writeSet.add(DIRECTORY + "/xmlCities/" + city.getGeoNameId() + ".xml", handle);
+            numCities++;
+        }
+        public void finishBatch() {
+            if ( writeSet.size() > 0 ) {
+                docMgr.write(writeSet);
+                // while this test is usually just 10 records so no more than one write set,
+                // we're ready to do more batches if we want to do performance testing here
+                writeSet = docMgr.newWriteSet();
+            }
+        }
+        public void setNumRecords(int numRecords) {}
+    }
+    
+    @Test
+    public void testXmlDatabind() throws Exception {
+        BulkReadWriteTest.loadCities(new XmlCityWriter());
+        // we can add assertions later, for now this test just serves as example code and 
+        // ensures no exceptions are thrown
+    }
+
+    /* The following fields are in the data but not the third-party pojo */
+    @JsonIgnoreProperties({"asciiName", "countryCode2", "dem", "timezoneCode", "lastModified"})
+    class ToponymMixIn1 {
+    }
+    
+    /* The following fields are either not in the third party pojo or not in the data so I don't want them serialized*/
+    @JsonIgnoreProperties({ 
+        "asciiName", "countryCode2", "dem", "timezoneCode", "lastModified",
+        "featureClassName", "featureCodeName", "countryName", "adminName1", "adminName2",
+        "elevation", "timezone", "style"
+    })
+    @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.WRAPPER_OBJECT)
+    class ToponymMixIn2 {
+    }
+
+    /** Demonstrate using Jackson's CSV mapper directly to simplify reading in data, populating a 
+     * third-party pojo (one we cannot annotate) then writing it out
+     * via JacksonDatabindHandle with configuration provided by mix-in annotations.
+     **/
+    @Test
+    public void testDatabindingThirdPartyPojoWithMixinAnnotations() throws JsonProcessingException, IOException {
+        CsvSchema schema = CsvSchema.builder()
+            .setColumnSeparator('\t')
+            .addColumn("geoNameId")
+            .addColumn("name")
+            .addColumn("asciiName")
+            .addColumn("alternateNames")
+            .addColumn("latitude", CsvSchema.ColumnType.NUMBER)
+            .addColumn("longitude", CsvSchema.ColumnType.NUMBER)
+            .addColumn("featureClass")
+            .addColumn("featureCode")
+            .addColumn("countryCode")
+            .addColumn("countryCode2")
+            .addColumn("adminCode1")
+            .addColumn("adminCode2")
+            .addColumn("adminCode3")
+            .addColumn("adminCode4")
+            .addColumn("population")
+            .addColumn("elevation", CsvSchema.ColumnType.NUMBER)
+            .addColumn("dem", CsvSchema.ColumnType.NUMBER)
+            .addColumn("timezoneCode")
+            .addColumn("lastModified")
+            .build();
+        CsvMapper mapper = new CsvMapper();
+        mapper.addMixInAnnotations(Toponym.class, ToponymMixIn1.class);
+        ObjectReader reader = mapper.reader(Toponym.class).with(schema);
+        BufferedReader cityReader = new BufferedReader(Common.testFileToReader(CITIES_FILE));
+        GenericDocumentManager docMgr = Common.client.newDocumentManager();
+        DocumentWriteSet set = docMgr.newWriteSet();
+        String line = null;
+        for (int numWritten = 0; numWritten < MAX_TO_WRITE && (line = cityReader.readLine()) != null; numWritten++ ) {
+            Toponym city = reader.readValue(line);
+            JacksonDatabindHandle handle = new JacksonDatabindHandle(city);
+            handle.getMapper().addMixInAnnotations(Toponym.class, ToponymMixIn2.class);
+            set.add(DIRECTORY + "/thirdPartyJsonCities/" + city.getGeoNameId() + ".json", handle);
+        }
+        docMgr.write(set);
+        cityReader.close();
+        // we can add assertions later, for now this test just serves as example code and 
+        // ensures no exceptions are thrown
+    }
+
+    public static void cleanUp() {
+        QueryManager queryMgr = Common.client.newQueryManager();
+        DeleteQueryDefinition deleteQuery = queryMgr.newDeleteDefinition();
+        deleteQuery.setDirectory(DIRECTORY);
+        queryMgr.delete(deleteQuery);
+    }
+}
diff --git a/src/test/java/com/marklogic/client/test/JacksonStreamTest.java b/src/test/java/com/marklogic/client/test/JacksonStreamTest.java
new file mode 100644
index 000000000..4ce92e56b
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/JacksonStreamTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.io.SerializedString;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.io.JacksonParserHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.test.Common;
+
+public class JacksonStreamTest {
+    private static final String ORDER_FILE = "sampleOrder.json";
+    private static final String ORDER_URI = "sampleOrder.json";
+    private static JSONDocumentManager docMgr;
+
+    @BeforeClass
+    public static void beforeClass() {
+        Common.connect();
+        docMgr = Common.client.newJSONDocumentManager();
+        setup();
+    }
+    @AfterClass
+    public static void afterClass() {
+        cleanUp();
+        Common.release();
+    }
+
+    
+    public class OrderItem {
+        private String productId;
+        private int quantity;
+        private float itemCostUSD;
+
+        public String getProductId() {
+            return productId;
+        }
+
+        public void setProductId(String productId) {
+            this.productId = productId;
+        }
+
+        public int getQuantity() {
+            return quantity;
+        }
+
+        public void setQuantity(int quantity) {
+            this.quantity = quantity;
+        }
+
+        public float getItemCostUSD() {
+            return itemCostUSD;
+        }
+
+        public void setItemCostUSD(float itemCostUSD) {
+            this.itemCostUSD = itemCostUSD;
+        }
+    }
+
+    /** Validate ability to read a stream of json content from the database using JsonParser.
+     * This test also demonstrates a scenario where we might want to do this, where we don't
+     * want to deserialize the entire json body because we only want a portion of the data.
+     */
+    @Test
+    public void testReadStream() throws IOException {
+        JacksonParserHandle handle = new JacksonParserHandle();
+        handle = docMgr.read(ORDER_URI, handle);
+        JsonParser jp = handle.get();
+        if (jp.nextToken() != JsonToken.START_OBJECT) {
+            throw new IOException("Expected data to start with an Object");
+        }
+        ArrayList orderItems = getOrderItems(jp);
+        assertEquals("orderItems array length is wrong", 4, orderItems.size());
+        assertEquals("OrderItem 1 productId is wrong", "widget",   orderItems.get(0).getProductId());
+        assertEquals("OrderItem 2 productId is wrong", "cog",      orderItems.get(1).getProductId());
+        assertEquals("OrderItem 3 productId is wrong", "spring",   orderItems.get(2).getProductId());
+        assertEquals("OrderItem 4 productId is wrong", "bearings", orderItems.get(3).getProductId());
+        assertEquals("OrderItem 1 quantity is wrong", 1, orderItems.get(0).getQuantity());
+        assertEquals("OrderItem 2 quantity is wrong", 5, orderItems.get(1).getQuantity());
+        assertEquals("OrderItem 3 quantity is wrong", 1, orderItems.get(2).getQuantity());
+        assertEquals("OrderItem 4 quantity is wrong", 3, orderItems.get(3).getQuantity());
+        assertEquals("OrderItem 1 itemCostUSD is wrong", 31.99, orderItems.get(0).getItemCostUSD(), 0.001);
+        assertEquals("OrderItem 2 itemCostUSD is wrong", 23.99, orderItems.get(1).getItemCostUSD(), 0.001);
+        assertEquals("OrderItem 3 itemCostUSD is wrong", 12.99, orderItems.get(2).getItemCostUSD(), 0.001);
+        assertEquals("OrderItem 4 itemCostUSD is wrong", 1.99,  orderItems.get(3).getItemCostUSD(), 0.001);
+    }
+
+    private ArrayList getOrderItems(JsonParser parser) throws IOException {
+        ArrayList orderItems = new ArrayList();
+        while ( parser.nextValue() != null ) {
+            if ( parser.getCurrentToken() == JsonToken.START_ARRAY &&
+                 "orderItems".equals(parser.getCurrentName()) )
+            {
+                while ( parser.nextValue() == JsonToken.START_OBJECT ) {
+                    OrderItem item = getOrderItem(parser);
+                    orderItems.add(item);
+                }
+                return orderItems;
+            }
+        }
+        return null;
+    }
+
+    private OrderItem getOrderItem(JsonParser parser) throws JsonParseException, IOException {
+        OrderItem item = new OrderItem();
+        if ( parser.getCurrentToken() != JsonToken.START_OBJECT ) {
+            throw new IllegalStateException("nextValue should have been START_OBJECT but is:[" + parser.getCurrentToken() + "]");
+        }
+        while ( parser.nextValue() != null ) {
+            if ( "productId".equals(parser.getCurrentName()) ) {
+                item.setProductId( parser.getText() );
+            } else if ( "quantity".equals(parser.getCurrentName()) ) {
+                item.setQuantity( parser.getIntValue() );
+            } else if ( "itemCostUSD".equals(parser.getCurrentName()) ) {
+                item.setItemCostUSD( parser.getFloatValue() );
+            }
+            if ( parser.getCurrentToken() == JsonToken.END_OBJECT ) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /** Demonstrates how to use a JsonGenerator to stream output that you then persist to the
+     * server using StringHandle (in this case, implicitly via writeAs).
+     */
+    @Test
+    public void testWriteStream() throws IOException {
+        JacksonParserHandle handle = new JacksonParserHandle();
+        handle = docMgr.read(ORDER_URI, handle);
+        JsonParser jp = handle.get();
+        if (jp.nextToken() != JsonToken.START_OBJECT) {
+            throw new IOException("Expected data to start with an Object");
+        }
+
+        StringWriter jsonWriter = new StringWriter();
+        JsonGenerator jsonStream = (new ObjectMapper()).getFactory().createGenerator(jsonWriter); 
+        // in this sample case we're copying everything up to and excluding the order
+        SerializedString order = new SerializedString("order");
+        do {
+            jsonStream.copyCurrentEvent(jp);
+        } while ( ! jp.nextFieldName(order) );
+        jsonStream.flush();
+        jsonStream.close();
+        docMgr.writeAs("testWriteStream.json", jsonWriter.toString());
+
+        JsonNode originalTree = docMgr.readAs(ORDER_URI, JsonNode.class);
+        JsonNode streamedTree = docMgr.readAs("testWriteStream.json", JsonNode.class);
+        assertEquals("customerName fields don't match", 
+            originalTree.get("customerName"), streamedTree.get("customerName"));
+        assertEquals("shipToAddress fields don't match", 
+            originalTree.get("shipToAddress"), streamedTree.get("shipToAddress"));
+        assertEquals("billingAddressRequired fields don't match", 
+            originalTree.get("billingAddressRequired"), streamedTree.get("billingAddressRequired"));
+    }
+
+    /** To make JacksonParserHandle a ContentHandle we had to implement set()
+     * which is a viable but admittedly corner case.  However, since it's implemented, let's
+     * make sure it works.  JsonParser.getInputSource() returns an InputStream or a Reader, 
+     * so we'll test to make sure behavior is the same whether the JsonParser was created 
+     * with a String, an InputStream, or a Reader.
+     */
+    @Test
+    public void testWriteParserCornerCase() throws IOException {
+        // test parsing a string
+        String fileString = Common.testFileToString(ORDER_FILE);
+        JsonParser parser = (new ObjectMapper()).getFactory().createParser(fileString); 
+        JacksonParserHandle handle = new JacksonParserHandle();
+        handle.set(parser);
+        docMgr.write("/testWriteParser1.json", handle);
+
+        // test parsing an InputStream
+        InputStream fileInputStream = Common.testFileToStream(ORDER_FILE);
+        parser = (new ObjectMapper()).getFactory().createParser(fileInputStream); 
+        handle = new JacksonParserHandle();
+        handle.set(parser);
+        docMgr.write("/testWriteParser2.json", handle);
+
+        // test parsing a Reader
+        Reader fileReader = Common.testFileToReader(ORDER_FILE);
+        parser = (new ObjectMapper()).getFactory().createParser(fileReader); 
+        handle = new JacksonParserHandle();
+        handle.set(parser);
+        docMgr.write("/testWriteParser3.json", handle);
+
+        JsonNode writeTree = (new ObjectMapper()).readTree(fileString);
+        JsonNode readTree1 = docMgr.readAs("/testWriteParser1.json", JsonNode.class);
+        JsonNode readTree2 = docMgr.readAs("/testWriteParser2.json", JsonNode.class);
+        JsonNode readTree3 = docMgr.readAs("/testWriteParser3.json", JsonNode.class);
+        assertEquals("readTree1 does not match writeTree", writeTree, readTree1);
+        assertEquals("readTree2 does not match writeTree", writeTree, readTree2);
+        assertEquals("readTree3 does not match writeTree", writeTree, readTree3);
+    }
+
+    private static void setup() {
+        ReaderHandle handle = new ReaderHandle(Common.testFileToReader(ORDER_FILE));
+        docMgr.write(ORDER_URI, handle);
+    }
+
+    private static void cleanUp() {
+        docMgr.delete(ORDER_URI);
+        docMgr.delete("testWriteStream.json");
+        docMgr.delete("testWriteParser1.json");
+        docMgr.delete("testWriteParser2.json");
+        docMgr.delete("testWriteParser3.json");
+    }
+}
+
diff --git a/src/test/java/com/marklogic/client/test/PojoFacadeTest.java b/src/test/java/com/marklogic/client/test/PojoFacadeTest.java
new file mode 100644
index 000000000..49042f3be
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/PojoFacadeTest.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.marklogic.client.pojo.PojoPage;
+import com.marklogic.client.pojo.PojoRepository;
+import com.marklogic.client.query.QueryDefinition;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.pojo.PojoQueryBuilder;
+import com.marklogic.client.test.BulkReadWriteTest;
+import com.marklogic.client.test.BulkReadWriteTest.CityWriter;
+
+import static com.marklogic.client.test.BulkReadWriteTest.DIRECTORY;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PojoFacadeTest {
+    private static final int MAX_TO_WRITE = 100;
+    private static PojoRepository cities;
+
+    @BeforeClass
+    public static void beforeClass() {
+        Common.connect();
+        cities = Common.client.newPojoRepository(City.class, Integer.class);
+        //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
+    }
+    @AfterClass
+    public static void afterClass() {
+        Common.release();
+    }
+
+    public class PojoCityWriter implements CityWriter {
+        private int numCities = 0;
+
+        public void addCity(City city) {
+            if ( numCities > MAX_TO_WRITE && !"Chittagong".equals(city.getName()) ) return;
+            cities.write(city);
+            numCities++;
+        }
+        public void finishBatch() {
+        }
+        public void setNumRecords(int numRecords) {
+            assertEquals("Number of records not expected", numRecords, BulkReadWriteTest.RECORDS_EXPECTED);
+        }
+    }
+    
+    @Test
+    public void testA_LoadPojos() throws Exception {
+        BulkReadWriteTest.loadCities(new PojoCityWriter());
+    }
+
+    @Test
+    public void testB_ReadPojos() throws Exception {
+        PojoPage page = cities.read(new Integer[]{1185098, 2239076, 1205733});
+        Iterator iterator = page.iterator();
+        int numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            validateCity(city);
+            numRead++;
+        }
+        assertEquals("Failed to read number of records expected", 3, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+    }
+
+    @Test
+    // the geo queries below currently don't work yet because underlying layers are not yet ready
+    public void testC_QueryPojos() throws Exception {
+        StringQueryDefinition stringQuery = Common.client.newQueryManager().newStringDefinition();
+        stringQuery.setCriteria("Tungi OR Dalatando OR Chittagong");
+        PojoPage page = cities.search(stringQuery, 1);
+        Iterator iterator = page.iterator();
+        int numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 3, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+
+        PojoQueryBuilder qb = cities.getQueryBuilder();
+        QueryDefinition query = qb.term("Tungi", "Dalatando", "Chittagong");
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 3, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        query = qb.value("continent", "AF");
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            assertEquals("Wrong continent", "AF", city.getContinent());
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 7, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        query = qb.containerQuery("alternateNames", qb.term("San", "Santo"));
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            String alternateNames = Arrays.asList(city.getAlternateNames()).toString();
+            assertTrue("Should contain San", alternateNames.contains("San"));
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 11, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        // test numeric (integer) values
+        query = qb.value("population", 374801);
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            assertEquals("Wrong City", "Tirana", city.getName());
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 1, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        // test numeric (fractional) values
+        query = qb.and(qb.value("latitude", -34.72418), qb.value("longitude", -58.25265));
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            assertEquals("Wrong City", "Quilmes", city.getName());
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 1, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        // test null values
+        query = qb.value("country", new String[] {null});
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 50, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        query = qb.range("population", Operator.LT, 350000);
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            City city = iterator.next();
+            numRead++;
+        }
+        assertEquals("Failed to find number of records expected", 21, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        // TODO: uncomment tests below once geospatial on JSON is implemented in server
+        /*
+        query = qb.geospatial(
+            qb.geoField("latLong"),
+            qb.circle(-34, -58, 1)
+        );
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            @SuppressWarnings("unused")
+            City city = iterator.next();
+            numRead++;
+        }
+        // this currently doesn't work even in the cts:search layer
+        // when this works we'll find out how many we expect
+        assertEquals("Failed to find number of records expected", -1, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        query = qb.geospatial(
+            qb.geoPath("latLong"),
+            qb.circle(-34, -58, 100)
+        );
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            @SuppressWarnings("unused")
+            City city = iterator.next();
+            numRead++;
+        }
+        // this currently doesn't work even in the cts:search layer
+        // when this works we'll find out how many we expect
+        assertEquals("Failed to find number of records expected", -1, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+
+        query = qb.geospatial(
+            qb.geoPair("latitude", "longitude"),
+            qb.circle(-34, -58, 100)
+        );
+        page = cities.search(query, 1);
+        iterator = page.iterator();
+        numRead = 0;
+        while ( iterator.hasNext() ) {
+            @SuppressWarnings("unused")
+            City city = iterator.next();
+            numRead++;
+        }
+        // this currently doesn't work even in the cts:search layer
+        // when this works we'll find out how many we expect
+        assertEquals("Failed to find number of records expected", -1, numRead);
+        assertEquals("PojoPage failed to report number of records expected", numRead, page.size());
+        */
+    }
+
+    @Test
+    public void testD_PojosWithChildren() throws Exception {
+        City dubai = cities.read(292223);
+        City abuDhabi = cities.read(292968);
+        City buenosAires = cities.read(3435910);
+
+        Country ae = new Country()
+            .setIsoCode("AE")
+            .setName("United Arab Emirates")
+            .setContinent("AS")
+            .setCurrencyCode("AED")
+            .setCurrencyName("Dirham");
+        dubai.setCountry( ae );
+        abuDhabi.setCountry( ae );
+
+        Country argentina = new Country()
+            .setIsoCode("AR")
+            .setName("Argentina")
+            .setContinent("SA")
+            .setCurrencyCode("ARS")
+            .setCurrencyName("Peso");
+        buenosAires.setCountry( argentina );
+
+        cities.write(dubai);
+        cities.write(abuDhabi);
+        cities.write(buenosAires);
+
+        PojoQueryBuilder qb = cities.getQueryBuilder();
+        PojoQueryBuilder countriesQb = qb.containerQuery("country");
+        QueryDefinition query = countriesQb.value("continent", "EU");
+        assertEquals("Should not find any countries", 0, cities.search(query, 1).getTotalSize());
+
+        query = countriesQb.value("continent", "AS");
+        assertEquals("Should find two cities", 2, cities.search(query, 1).getTotalSize());
+
+        query = countriesQb.range("continent", Operator.EQ, "AS");
+        assertEquals("Should find two cities", 2, cities.search(query, 1).getTotalSize());
+
+        // all countries containing the term SA
+        query = countriesQb.containerQuery(countriesQb.term("SA"));
+        assertEquals("Should find one city", 1, cities.search(query, 1).getTotalSize());
+
+        // all cities containing the term SA
+        query = qb.containerQuery(qb.term("SA"));
+        assertEquals("Should find two cities", 61, cities.search(query, 1).getTotalSize());
+
+        // all countries containing the field "currencyName" with the term "peso"
+        query = countriesQb.word("currencyName", "peso");
+        assertEquals("Should find one city", 1, cities.search(query, 1).getTotalSize());
+    }
+
+    @Test
+    public void testE_DeletePojos() throws Exception {
+        cities.delete(1185098, 2239076);
+        StringQueryDefinition query = Common.client.newQueryManager().newStringDefinition();
+        query.setCriteria("Tungi OR Dalatando OR Chittagong");
+        PojoPage page = cities.search(query, 1);
+        assertEquals("Failed to read number of records expected", 1, page.getTotalSize());
+
+        // now delete them all
+        cities.deleteAll();
+        long count = cities.count();
+        assertEquals("Failed to read number of records expected", 0, count);
+    }
+
+    private void validateCity(City city) {
+        assertNotNull("City should never be null", city);
+        assertNotNull("GeoNamId should never be null", city.getGeoNameId());
+        if ( "Chittagong".equals(city.getName()) ) {
+            BulkReadWriteTest.validateChittagong(city);
+        }
+    }
+}
diff --git a/src/test/java/com/marklogic/client/test/QueryByExampleTest.java b/src/test/java/com/marklogic/client/test/QueryByExampleTest.java
new file mode 100644
index 000000000..8e6bfb8c0
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/QueryByExampleTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2013-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.JacksonHandle;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.DeleteQueryDefinition;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawQueryByExampleDefinition;
+
+public class QueryByExampleTest {
+    @BeforeClass
+    public static void beforeClass() {
+        Common.connectAdmin();
+        //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
+        setupData();
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        cleanUpData();
+        Common.release();
+    }
+
+    @Test
+    public void jsonQbe() {
+        JSONDocumentManager jdm = Common.client.newJSONDocumentManager();
+        QueryManager qm = Common.client.newQueryManager();
+        String queryAsString = "{ \"$query\": { \"kind\": \"bird\" }    }";
+        StringHandle handle = new StringHandle();
+        handle.withFormat(Format.JSON).set(queryAsString);      
+        RawQueryByExampleDefinition query = 
+                qm.newRawQueryByExampleDefinition(handle);
+
+        StringHandle report = qm.validate(query, new StringHandle());
+        System.out.println(report.toString());
+
+        SearchHandle results = qm.search(query, new SearchHandle());
+        assertEquals("6 json results should have matched", results.getTotalResults(), 6);
+        
+        DocumentPage documents = jdm.search(query, 1);
+        assertEquals("6 json documents should have matched", documents.getTotalSize(), 6);
+        
+        documents = jdm.search(query, 1, new JacksonHandle());
+        assertEquals("6 json documents should have matched", documents.getTotalSize(), 6);
+        
+        jdm.setResponseFormat(Format.XML);
+        documents = jdm.search(query, 1, new SearchHandle());
+        assertEquals("6 json documents should have matched", documents.getTotalSize(), 6);
+    }
+
+    @Test
+    public void xmlQbe() {
+        XMLDocumentManager xdm = Common.client.newXMLDocumentManager();
+        QueryManager qm = Common.client.newQueryManager();
+        String queryAsString = 
+            ""+
+                "" +
+                  "bird" +
+                "" +
+              "";
+        RawQueryByExampleDefinition query = 
+                qm.newRawQueryByExampleDefinition(new StringHandle(queryAsString));
+
+        StringHandle report = qm.validate(query, new StringHandle());
+        System.out.println(report.toString());
+
+        SearchHandle results = qm.search(query, new SearchHandle());
+        assertEquals("No XML results should have matched", results.getTotalResults(), 0);
+
+        DocumentPage documents = xdm.search(query, 1);
+        assertEquals("No XML documents should have matched", documents.getTotalSize(), 0);
+
+        documents = xdm.search(query, 1, new DOMHandle());
+        assertEquals("No XML documents should have matched", documents.getTotalSize(), 0);
+    }
+
+    public static void setupData() {
+        JSONDocumentManager docMgr = Common.client.newJSONDocumentManager();
+        DocumentWriteSet writeSet = docMgr.newWriteSet();
+        String[] animals = new String[] {
+            "{ \"name\": \"aardvark\",  \"kind\": \"mammal\" }",
+            "{ \"name\": \"badger\",    \"kind\": \"mammal\" }",
+            "{ \"name\": \"camel\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"duck\",      \"kind\": \"bird\" }",
+            "{ \"name\": \"emu\",       \"kind\": \"bird\" }",
+            "{ \"name\": \"fox\",       \"kind\": \"mammal\" }",
+            "{ \"name\": \"goose\",     \"kind\": \"bird\" }",
+            "{ \"name\": \"hare\",      \"kind\": \"mammal\" }",
+            "{ \"name\": \"ibex\",      \"kind\": \"bird\" }",
+            "{ \"name\": \"jaguar\",    \"kind\": \"mammal\" }",
+            "{ \"name\": \"kangaroo\",  \"kind\": \"marsupial\" }",
+            "{ \"name\": \"lemur\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"moose\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"nighthawk\", \"kind\": \"bird\" }",
+            "{ \"name\": \"ocelot\",    \"kind\": \"mammal\" }",
+            "{ \"name\": \"panda\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"rhino\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"snake\",     \"kind\": \"reptile\" }",
+            "{ \"name\": \"turtle\",    \"kind\": \"reptile\" }",
+            "{ \"name\": \"urial\",     \"kind\": \"mammal\" }",
+            "{ \"name\": \"vulture\",   \"kind\": \"bird\" }",
+            "{ \"name\": \"wallaby\",   \"kind\": \"marsupial\" }",
+            "{ \"name\": \"yak\",       \"kind\": \"mammal\" }",
+            "{ \"name\": \"zebra\",     \"kind\": \"mammal\" }"
+        };
+        for ( int i=0; i < animals.length; i++ ) {
+            String animal = animals[i];
+            writeSet.add( "/animals/" + i + ".json", new StringHandle(animal).withFormat(Format.JSON));
+        }
+        docMgr.write(writeSet);
+    }
+
+    public static void cleanUpData() {
+        QueryManager qm = Common.client.newQueryManager();
+        DeleteQueryDefinition deleteQuery = qm.newDeleteDefinition();
+        deleteQuery.setDirectory("/animals/");
+        qm.delete(deleteQuery);
+    }
+}
diff --git a/src/test/java/com/marklogic/client/test/RawQueryDefinitionTest.java b/src/test/java/com/marklogic/client/test/RawQueryDefinitionTest.java
index ead1ea409..347514dfd 100644
--- a/src/test/java/com/marklogic/client/test/RawQueryDefinitionTest.java
+++ b/src/test/java/com/marklogic/client/test/RawQueryDefinitionTest.java
@@ -62,6 +62,7 @@ public class RawQueryDefinitionTest {
 	public static void beforeClass() {
 		Common.connectAdmin();
 		queryMgr = Common.client.newQueryManager();
+		//System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
 	}
 
 	@AfterClass
@@ -276,7 +277,7 @@ public void testByExampleSearch() throws IOException, SAXException, XpathExcepti
 						"\"$query\":{\"favorited\":\"true\"}"+
 						"}"
 						);
-		output = queryMgr.search(qbe, new StringHandle()).get();
+		output = queryMgr.search(qbe, new StringHandle().withFormat(Format.JSON)).get();
 		assertNotNull("Empty JSON output", output);
 		assertTrue("Output without a match",
 				output.contains("\"results\":[{\"index\":1,"));
diff --git a/src/test/java/com/marklogic/client/test/SSLTest.java b/src/test/java/com/marklogic/client/test/SSLTest.java
new file mode 100644
index 000000000..aaa131aa7
--- /dev/null
+++ b/src/test/java/com/marklogic/client/test/SSLTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2012-2014 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.marklogic.client.test;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+
+import org.junit.Test;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.DatabaseClientFactory.SSLHostnameVerifier;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.io.StringHandle;
+
+public class SSLTest {
+    @Test
+    public void testSSLAuth() throws NoSuchAlgorithmException, KeyManagementException {
+
+        // create a trust manager
+        // (note: a real application should verify certificates)
+        TrustManager naiveTrustMgr = new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(X509Certificate[] chain, String authType) {
+            }
+            @Override
+            public void checkServerTrusted(X509Certificate[] chain, String authType) {
+            }
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+        };
+
+        // create an SSL context
+        SSLContext sslContext = SSLContext.getInstance("SSLv3");
+        sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+
+        // create the client
+        DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8012, "MyFooUser", "x", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+
+        String expectedException = "com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated";
+        String exception = "";
+
+        try {
+            // make use of the client connection so we get an auth error
+            TextDocumentManager docMgr = client.newTextDocumentManager();
+            String docId = "/example/text.txt";
+            StringHandle handle = new StringHandle();
+            handle.set("A simple text document");
+            docMgr.write(docId, handle);
+            // the next line will only run if write doesn't throw an exception
+            docMgr.delete(docId);
+        }
+        catch (Exception e) {
+            exception = e.toString();
+        }
+        assertEquals(expectedException, exception);
+
+    }
+}
diff --git a/src/test/resources/bootstrap.xqy b/src/test/resources/bootstrap.xqy
index 61507942c..c0b37e0be 100644
--- a/src/test/resources/bootstrap.xqy
+++ b/src/test/resources/bootstrap.xqy
@@ -194,6 +194,28 @@ as empty-sequence()
         if (empty($index-specs)) then $c
         else admin:database-add-range-field-index($c, $dbid, $index-specs)
 
+    let $index-specs := admin:database-range-path-index(
+      $dbid, 
+      "string",
+      "com.marklogic.client.test.Country/continent",
+      "http://marklogic.com/collation/",
+      fn:false(),
+      "ignore")
+    let $c :=
+        if (empty($index-specs)) then $c
+        else admin:database-add-range-path-index($c, $dbid, $index-specs)
+
+    let $index-specs := admin:database-range-path-index(
+      $dbid, 
+      "unsignedLong",
+      "com.marklogic.client.test.City/population",
+      (),
+      fn:false(),
+      "ignore")
+    let $c :=
+        if (empty($index-specs)) then $c
+        else admin:database-add-range-path-index($c, $dbid, $index-specs)
+
     return admin:save-configuration-without-restart($c)
 };
 
diff --git a/src/test/resources/sampleOrder.json b/src/test/resources/sampleOrder.json
new file mode 100644
index 000000000..64d486173
--- /dev/null
+++ b/src/test/resources/sampleOrder.json
@@ -0,0 +1,39 @@
+{   "customerName": "Joe Shmoe",
+    "shipToAddress": {
+        "address1":   "123 Some Lane",
+        "address2":   "",
+        "city":       "Beverly Hills",
+        "postalCode": "90210",
+        "country":    "US"
+    },
+    "billingAddressRequired": false,
+    "order": {
+        "date":                "2014/01/01",
+        "totalUSD":            170.90,
+        "paymentMethod":       "paypal",
+        "payPalTransactionId": "P1234567890",
+        "orderItems": [
+            {   "productId":   "widget",
+                "quantity":    1,
+                "itemCostUSD": 31.99,
+                "totalUSD":    31.99
+            },
+            {   "productId":   "cog",
+                "quantity":    5,
+                "itemCostUSD": 23.99,
+                "totalUSD":    119.95
+            },
+            {   "productId":   "spring",
+                "quantity":    1,
+                "itemCostUSD": 12.99,
+                "totalUSD":    12.99
+            },
+            {   "productId":   "bearings",
+                "quantity":    3,
+                "itemCostUSD": 1.99,
+                "totalUSD":    5.97
+            }
+        ]
+    }
+}
+        
diff --git a/test-complete/build.gradle b/test-complete/build.gradle
new file mode 100644
index 000000000..2ad90743b
--- /dev/null
+++ b/test-complete/build.gradle
@@ -0,0 +1,16 @@
+
+/* plugins */
+apply plugin: 'java'
+
+
+/* The code repositories to consult for dependencies */
+repositories {
+    mavenLocal()
+    mavenCentral()
+}
+
+dependencies {
+    compile('com.marklogic:client-api-java:3.0-SNAPSHOT')
+	compile('xmlunit:xmlunit:1.5')
+	compile('junit:junit:4.11')
+}
diff --git a/test-complete/gradle/wrapper/gradle-wrapper.jar b/test-complete/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..583859812
Binary files /dev/null and b/test-complete/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/test-complete/gradle/wrapper/gradle-wrapper.properties b/test-complete/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..c2dcf0ce5
--- /dev/null
+++ b/test-complete/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jun 12 15:41:44 PDT 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/test-complete/gradlew b/test-complete/gradlew
new file mode 100644
index 000000000..91a7e269e
--- /dev/null
+++ b/test-complete/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/test-complete/gradlew.bat b/test-complete/gradlew.bat
new file mode 100644
index 000000000..8a0b282aa
--- /dev/null
+++ b/test-complete/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/test-complete/myHelp.txt b/test-complete/myHelp.txt
new file mode 100644
index 000000000..98405ab13
--- /dev/null
+++ b/test-complete/myHelp.txt
@@ -0,0 +1,18 @@
+Step 1: 
+ Build dev source code by doing the following on your dev branch
+
+Mvn clean
+Mvn Dmaven.test.skip=true install
+
+Step2:
+Go to the directory where you ../test-complete/
+
+Gradlew clean
+
+Gradlew test    => to run all the functional tests, which will take about couple of hours
+
+gradlew -Dtest.single=TestBulkWriteMetadata1 test    => to run individual tests
+
+each test is independent and you can find the results under Java-client-api-qa\build\test-results
+
+and if you run all the functional tests then you can find a report under Java-client-api-qa\build\reports\tests\index.html
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/BasicJavaClientREST.java b/test-complete/src/test/java/com/marklogic/javaclient/BasicJavaClientREST.java
new file mode 100644
index 000000000..dd0fcf164
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/BasicJavaClientREST.java
@@ -0,0 +1,1764 @@
+package com.marklogic.javaclient;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+
+
+
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+//import sun.java2d.loops.XorPixelWriter.ByteData;
+
+
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.MatchLocation;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.InputSourceHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.JAXBHandle;
+import com.marklogic.client.io.OutputStreamHandle;
+import com.marklogic.client.io.OutputStreamSender;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.XMLEventReaderHandle;
+import com.marklogic.client.io.XMLStreamReaderHandle;
+
+
+
+//import com.sun.xml.internal.ws.util.xml.StAXSource;
+//Importing for http client calls
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.util.*;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.client.entity.*;
+
+
+public abstract class BasicJavaClientREST extends ConnectedRESTQA
+{
+    protected static String checkDoc =
+    	"xquery version '1.0-ml';\n" +
+    	"fn:doc('/bar/test/myBar.txt')";
+	
+    public BasicJavaClientREST() {
+		
+	}
+	
+	/**
+	 * Write document using InputStreamHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws FileNotFoundException 
+	 */
+	public void writeDocumentUsingInputStreamHandle(DatabaseClient client, String filename, String uri, String type) throws FileNotFoundException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+
+		// create handle
+		InputStreamHandle contentHandle = new InputStreamHandle();
+
+		// get the file
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// set uri
+		String docId = uri + filename;
+
+		contentHandle.set(inputStream);
+			
+		// write doc
+		docMgr.write(docId, contentHandle);
+		
+		System.out.println("Write " + docId + " to database");
+	}
+	
+	/**
+	 * Write document using InputStreamHandle with metadata
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @param metadataHandle
+	 * @throws FileNotFoundException
+	 */
+	public void writeDocumentUsingInputStreamHandle(DatabaseClient client, String filename, String uri, DocumentMetadataHandle metadataHandle, String type) throws FileNotFoundException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+
+		// create handle
+		InputStreamHandle contentHandle = new InputStreamHandle();
+
+		// get the file
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// set uri
+		String docId = uri + filename;
+
+		contentHandle.set(inputStream);
+			
+		// write doc
+		docMgr.write(docId, metadataHandle, contentHandle);
+		
+		System.out.println("Write " + docId + " to database");
+	}
+
+	public void writeDocumentUsingInputStreamHandle(DatabaseClient client, String filename, String uri, Transaction transaction, String type) throws FileNotFoundException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+
+		// create handle
+		InputStreamHandle contentHandle = new InputStreamHandle();
+
+		// get the file
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// set uri
+		String docId = uri + filename;
+
+		contentHandle.set(inputStream);
+			
+		// write doc
+		docMgr.write(docId, contentHandle, transaction);
+		
+		System.out.println("Write " + docId + " to database");
+	}
+		
+	/**
+	 * Reading document using InputStreamHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public InputStreamHandle readDocumentUsingInputStreamHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		InputStreamHandle contentHandle = new InputStreamHandle();
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;
+	}
+	/**
+	 * Reading document using InputSourceHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	
+	public InputSourceHandle readDocumentUsingInputSourceHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		InputSourceHandle contentHandle = new InputSourceHandle();		
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;
+	}
+	/**
+	 * Reading document using SourceHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	
+	public SourceHandle readDocumentUsingSourceHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		SourceHandle contentHandle = new SourceHandle();		
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;
+	}
+	
+	
+	/**
+	 * Update document using InputStreamHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws FileNotFoundException
+	 */
+	public void updateDocumentUsingInputStreamHandle(DatabaseClient client, String filename, String uri, String type) throws FileNotFoundException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+
+		// create handle
+		InputStreamHandle contentHandle = new InputStreamHandle();
+
+		// get the file
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// set uri
+		String docId = uri;
+
+		contentHandle.set(inputStream);
+			
+		// write doc
+		docMgr.write(docId, contentHandle);
+		
+		System.out.println("Update " + docId + " to database");
+	}
+
+	/**
+	 * Write document using BytesHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException
+	 */
+	public void writeDocumentUsingBytesHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+	{
+		// get the content to bytes
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);		 
+        FileInputStream fis = new FileInputStream(file);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        for (int readNum; (readNum = fis.read(buf)) != -1;) 
+        {
+            bos.write(buf, 0, readNum);
+        }
+        
+        byte[] bytes = bos.toByteArray();
+        
+        fis.close();
+        bos.close();
+        
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+	 
+		String docId = uri + filename;
+		
+	    // create handle
+	    BytesHandle contentHandle = new BytesHandle();
+	    contentHandle.set(bytes);
+	    
+	    // write the doc
+	    docMgr.write(docId, contentHandle);
+	    
+	    System.out.println("Write " + docId + " to the database");
+	}
+		
+	/**
+	 * Write document using BytesHandle with metadata
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param metadataHandle
+	 * @param type
+	 * @throws IOException
+	 */
+	public void writeDocumentUsingBytesHandle(DatabaseClient client, String filename, String uri, DocumentMetadataHandle metadataHandle, String type) throws IOException
+	{
+		// get the content to bytes
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);		 
+        FileInputStream fis = new FileInputStream(file);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        for (int readNum; (readNum = fis.read(buf)) != -1;) 
+        {
+            bos.write(buf, 0, readNum);
+        }
+        
+        byte[] bytes = bos.toByteArray();
+        
+        fis.close();
+        bos.close();
+        
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+	 
+		String docId = uri + filename;
+		
+	    // create handle
+	    BytesHandle contentHandle = new BytesHandle();
+	    contentHandle.set(bytes);
+	    
+	    // write the doc
+	    docMgr.write(docId, metadataHandle, contentHandle);
+	    
+	    System.out.println("Write " + docId + " to the database");
+	}
+
+        /**
+         * Write document using StringHandle with metadata
+         * @param client
+         * @param filename
+         * @param uri
+         * @param metadataHandle
+         * @param type
+         * @throws IOException
+         */
+        public void writeDocumentUsingStringHandle(DatabaseClient client, String filename, String uri, DocumentMetadataHandle metadataHandle, String type) throws IOException
+        {
+                // acquire the content
+                File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+        FileInputStream fis = new FileInputStream(file);
+            Scanner scanner = new Scanner(fis).useDelimiter("\\Z");
+            String readContent = scanner.next();
+            fis.close();
+            scanner.close();
+
+                // create doc manager
+                DocumentManager docMgr = null;
+                docMgr = documentManagerSelector(client, docMgr, type);
+
+                String docId = uri + filename;
+
+            // create handle
+            StringHandle contentHandle = new StringHandle();
+            contentHandle.set(readContent);
+
+            // write the doc
+            docMgr.write(docId, metadataHandle, contentHandle);
+
+            System.out.println("Write " + docId + " to the database");
+        }
+	
+        /**
+         * Write document using StringHandle
+         * @param client
+         * @param filename
+         * @param uri
+         * @param type
+         * @throws IOException
+         */
+        public void writeDocumentUsingStringHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+        {
+                // acquire the content
+                File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+        FileInputStream fis = new FileInputStream(file);
+            Scanner scanner = new Scanner(fis).useDelimiter("\\Z");
+            String readContent = scanner.next();
+            fis.close();
+            scanner.close();
+
+                // create doc manager
+                DocumentManager docMgr = null;
+                docMgr = documentManagerSelector(client, docMgr, type);
+
+                String docId = uri + filename;
+
+            // create handle
+            StringHandle contentHandle = new StringHandle();
+            contentHandle.set(readContent);
+
+            // write the doc
+            docMgr.write(docId, contentHandle);
+
+            System.out.println("Write " + docId + " to the database");
+        }
+	
+	/**
+	 * Write document using JAXBHandle with metadata
+	 * @param client
+	 * @param product
+	 * @param uri
+	 * @param metadataHandle
+	 * @param type
+	 * @throws JAXBException
+	 */
+	public void writeDocumentUsingJAXBHandle(DatabaseClient client, Product product, String uri, DocumentMetadataHandle metadataHandle, String type) throws JAXBException
+	{
+		// set jaxb context 
+		JAXBContext context = JAXBContext.newInstance(Product.class);
+		
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+		
+	    // create an identifier for the document
+	    String docId = uri + product.getName() + ".xml";
+
+	    // create a handle on the content
+	    JAXBHandle contentHandle = new JAXBHandle(context);
+	    contentHandle.set(product);
+	    
+	    // write the doc
+	    docMgr.write(docId, metadataHandle, contentHandle);
+	    
+	    System.out.println("Write " + docId + " to the database");
+	}
+	
+	/**
+	 * Write document using OutputStreamHandle with metadata
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param metadataHandle
+	 * @param type
+	 */
+	public void writeDocumentUsingOutputStreamHandle(DatabaseClient client, final String filename, String uri, DocumentMetadataHandle metadataHandle, String type)
+	{
+		final int MAX_BUF = 1024;
+		
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+	 
+		String docId = uri + filename;
+		
+		// create an anonymous class with a callback method
+		OutputStreamSender sender = new OutputStreamSender() {
+            // the callback receives the output stream
+			public void write(OutputStream out) throws IOException {
+        		// acquire the content
+				InputStream docStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+				
+        		// copy content to the output stream
+        		byte[] buf = new byte[MAX_BUF];
+        		int byteCount = 0;
+        		while ((byteCount=docStream.read(buf)) != -1) {
+        			out.write(buf, 0, byteCount);
+        		}
+            }
+        };
+        
+        // create the handle
+        OutputStreamHandle contentHandle = new OutputStreamHandle(sender);
+        
+     // write the doc
+	    docMgr.write(docId, metadataHandle, contentHandle);
+	    
+        System.out.println("Write " + docId + " to the database");
+	}
+	public void writeDocumentUsingOutputStreamHandle(DatabaseClient client, final String filename, String uri, String type)
+	{
+		final int MAX_BUF = 1024;
+		
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+	 
+		String docId = uri + filename;
+		
+		// create an anonymous class with a callback method
+		OutputStreamSender sender = new OutputStreamSender() {
+            // the callback receives the output stream
+			public void write(OutputStream out) throws IOException {
+        		// acquire the content
+				InputStream docStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+				
+        		// copy content to the output stream
+        		byte[] buf = new byte[MAX_BUF];
+        		int byteCount = 0;
+        		while ((byteCount=docStream.read(buf)) != -1) {
+        			out.write(buf, 0, byteCount);
+        		}
+            }
+        };
+        
+        // create the handle
+        OutputStreamHandle contentHandle = new OutputStreamHandle(sender);
+        
+     // write the doc
+	    docMgr.write(docId, contentHandle);
+	    
+        System.out.println("Write " + docId + " to the database");
+	}
+	public void updateDocumentUsingOutputStreamHandle(DatabaseClient client,final String filename, String uri, String type) throws FileNotFoundException
+	{
+		final int MAX_BUF = 1024;
+		
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+	
+		String docId = uri;
+		
+		// create an anonymous class with a callback method
+		OutputStreamSender sender = new OutputStreamSender() {
+            // the callback receives the output stream
+			public void write(OutputStream out) throws IOException {
+        		// acquire the content
+				InputStream docStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+				
+        		// copy content to the output stream
+        		byte[] buf = new byte[MAX_BUF];
+        		int byteCount = 0;
+        		while ((byteCount=docStream.read(buf)) != -1) {
+        			out.write(buf, 0, byteCount);
+        		}
+            }
+        };
+
+		// create handle
+		OutputStreamHandle contentHandle = new OutputStreamHandle(sender);
+		// set uri
+		// write doc
+		docMgr.write(docId, contentHandle);
+		
+		System.out.println("Update " + docId + " to database");
+	}
+	/**
+	 * Write document to databae using ReaderHandle
+	 * @param client: the database client connection
+	 * @param filename: the filename 
+	 * @param uri: the document uri
+	 * @param type: the document type (XML, Text, JSON, or Binary)
+	 * @throws IOException 
+	 */
+	public void writeDocumentReaderHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+	{   
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// acquire the content
+		BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/data/" + filename));
+			 
+	    // create an identifier for the document
+		String docId = uri + filename;
+	    
+	    // create a handle on the content
+	    ReaderHandle handle = new ReaderHandle();
+	    handle.set(docStream);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Write " + docId + " to database");
+	    
+	    docStream.close();
+	}
+	
+	/**
+	 * Update document using ReaderHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException 
+	 */
+	public void updateDocumentReaderHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+		
+		// acquire the content
+		BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/data/" + filename));
+			 
+	    // create an identifier for the document
+		String docId = uri;
+	    
+	    // create a handle on the content
+	    ReaderHandle handle = new ReaderHandle();
+	    handle.set(docStream);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Update " + docId + " to database");	
+	    
+	    docStream.close();
+	}
+
+	/**
+	 * Read document using ReaderHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public ReaderHandle readDocumentReaderHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// create handle
+		ReaderHandle readerHandle = new ReaderHandle();
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, readerHandle);
+		
+		return readerHandle;
+	}
+	/**
+	 * Read document using XMLEventReaderHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public XMLEventReaderHandle readDocumentUsingXMLEventReaderHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// create handle
+		XMLEventReaderHandle readerHandle = new XMLEventReaderHandle();
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, readerHandle);
+		
+		return readerHandle;
+	}
+	
+	public XMLStreamReaderHandle readDocumentUsingXMLStreamReaderHandle (DatabaseClient client, String uri, String type){
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// create handle
+		XMLStreamReaderHandle readerHandle = new XMLStreamReaderHandle();
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, readerHandle);
+		
+		return readerHandle;
+	}
+	/**
+	 * Write document using DOMHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException
+	 * @throws ParserConfigurationException 
+	 * @throws SAXException 
+	 */
+	public void writeDocumentUsingDOMHandle(DatabaseClient client, String filename, String uri, String type) throws IOException, ParserConfigurationException, SAXException
+	{   
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// acquire the content
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document content = docBuilder.parse(new File("src/test/java/com/marklogic/javaclient/data/" + filename));
+			 
+	    // create an identifier for the document
+		String docId = uri + filename;
+	    
+	    // create a handle on the content
+	    DOMHandle handle = new DOMHandle();
+	    handle.set(content);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Write " + docId + " to database");
+	}
+	/**
+	 * Returning a content of the document
+	 * 
+	 */
+	
+	public Document getDocumentContent(String xmltype) throws IOException, ParserConfigurationException, SAXException
+	{
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document content = docBuilder.newDocument();
+		Element rootElement = content.createElement("foo");
+		rootElement.appendChild(content.createTextNode(xmltype));
+		content.appendChild(rootElement);
+		
+//		content.createTextNode(xmltype);
+		return content;
+		
+				
+			
+	}
+	/**
+	 * Update document using DOMHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException
+	 * @throws ParserConfigurationException
+	 * @throws SAXException
+	 */
+	public void updateDocumentUsingDOMHandle(DatabaseClient client, String filename, String uri, String type) throws IOException, ParserConfigurationException, SAXException
+	{   
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+				
+		// acquire the content
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document content = docBuilder.parse(new File("src/test/java/com/marklogic/javaclient/data/" + filename));
+			 
+	    // create an identifier for the document
+		String docId = uri;
+	    
+	    // create a handle on the content
+	    DOMHandle handle = new DOMHandle();
+	    handle.set(content);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Update " + docId + " to database");
+	}
+	
+	/**
+	 * Read document using DOMHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public DOMHandle readDocumentUsingDOMHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		DOMHandle contentHandle = new DOMHandle();
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;
+	}
+	/**
+	 * Read document using JAXBHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 * @throws JAXBException 
+	 */
+	public JAXBHandle readDocumentUsingJAXBHandle(DatabaseClient client, String uri, String type) throws JAXBException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		JAXBContext con = JAXBContext.newInstance(Product.class);
+		JAXBHandle contentHandle = new JAXBHandle(con);
+		
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;
+	}
+        /**
+         * Read document using StringHandle
+         * @param client
+         * @param uri
+         * @param type
+         * @return
+         */
+        public StringHandle readDocumentUsingStringHandle(DatabaseClient client, String uri, String type)
+        {
+                // create doc manager
+                DocumentManager docMgr = null;
+                docMgr = documentManagerSelector(client, docMgr, type);
+
+                // create handle
+                StringHandle contentHandle = new StringHandle();
+//                contentHandle.set(readContent);
+
+                // create doc id
+                String readDocId = uri;
+                System.out.println("Read " + readDocId + " from database");
+
+                docMgr.read(readDocId, contentHandle);
+
+                return contentHandle;
+        }
+	
+	/**
+	 * Write document using FileHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException
+	 */
+	public void writeDocumentUsingFileHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+				
+	    // create an identifier for the document
+		String docId = uri + filename;
+	    
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Write " + docId + " to database");		
+	}
+
+	/**
+	 * Read document using FileHandle
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public FileHandle readDocumentUsingFileHandle(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		// create handle
+		FileHandle contentHandle = new FileHandle();
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		
+		docMgr.read(readDocId, contentHandle);
+		
+		return contentHandle;		
+	}
+	
+	/**
+	 * Update document using FileHandle
+	 * @param client
+	 * @param filename
+	 * @param uri
+	 * @param type
+	 * @throws IOException
+	 */
+	public void updateDocumentUsingFileHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+			    	 
+	    // create an identifier for the document
+		String docId = uri;
+	    
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Update " + docId + " to database");		
+	}
+
+        /**
+         * Update document using FileHandle
+         * @param client
+         * @param filename
+         * @param uri
+         * @param type
+         * @throws IOException
+         */
+        public void updateDocumentUsingStringHandle(DatabaseClient client, String filename, String uri, String type) throws IOException
+        {
+            // create doc manager
+            DocumentManager docMgr = null;
+            docMgr = documentManagerSelector(client, docMgr, type);
+
+            File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+            FileInputStream fis = new FileInputStream(file);
+            Scanner scanner = new Scanner(fis).useDelimiter("\\Z");
+            String readContent = scanner.next();
+            fis.close();
+            scanner.close();
+
+            // create an identifier for the document
+            String docId = uri;
+
+            // create a handle on the content
+            // create handle
+            StringHandle contentHandle = new StringHandle();
+            contentHandle.set(readContent);
+
+            // write the document content
+            docMgr.write(docId, contentHandle);
+
+            System.out.println("Update " + docId + " to database");
+        }
+
+        /**
+         * Read document using BytesHandle
+         * @param client
+         * @param uri
+         * @param type
+         * @throws IOException
+         */
+	public BytesHandle readDocumentUsingBytesHandle(DatabaseClient client, String uri, String type)throws IOException , NullPointerException
+	{
+		//create doc manager
+		DocumentManager docMgr = null;
+		docMgr=documentManagerSelector(client, docMgr, type);
+
+		//create handle
+		BytesHandle contentHandle = new BytesHandle();
+		
+		//create doc id
+		String readDocId = uri;
+		System.out.println("Read " + readDocId + " from database");
+		docMgr.read(readDocId, contentHandle);
+		return contentHandle;
+		
+	}
+        /**
+         * get Binary Size From Byte
+         * @param binaryFileInByte 
+         * @throws IOException
+         */
+	public int getBinarySizeFromByte(byte[] fileRead) throws IOException, IndexOutOfBoundsException
+	{
+		ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+		byte[] b = new byte[1000];
+		int len = fileRead.length;
+		
+		return len;
+	}
+
+        /**
+         * Read document using BytesHandle
+         * @param client
+         * @param filename
+         * @param uri
+         * @param type
+         * @throws IOException
+         */
+	public void updateDocumentUsingByteHandle(DatabaseClient client, String filename, String uri, String type) throws IOException, ParserConfigurationException, SAXException
+	{   
+	    // create doc manager
+	    DocumentManager docMgr = null;
+	    docMgr = documentManagerSelector(client, docMgr, type);	
+				
+	    // acquire the content
+	    FileReader content = new FileReader("src/test/java/com/marklogic/javaclient/data/" + filename);
+	    //String contentInString = new String(content);
+	    BufferedReader br = new BufferedReader(content);
+	    String readContent = "";
+	    String line = null;
+	    while ((line = br.readLine()) != null)
+	    		readContent = readContent + line; 
+	    br.close();
+
+	    byte[] contentInByte = (byte[])readContent.getBytes();
+	    // create an identifier for the document
+	    String docId = uri;
+	    // create a handle on the content
+	    BytesHandle handle = new BytesHandle();
+	    handle.set(contentInByte);
+	        
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Update " + docId + " to database");
+	}
+
+	
+	/**
+	 * Delete document
+	 * @param client
+	 * @param uri
+	 * @param type
+	 */
+	public void deleteDocument(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);	
+
+		String deleteDocId = uri;
+
+		docMgr.delete(deleteDocId);
+		System.out.println("Delete " + deleteDocId + " from database");
+	}
+	
+	/**
+	 * Check if document exist
+	 * @param client
+	 * @param uri
+	 * @return
+	 */
+	/*public DocumentDescriptor isDocumentExist(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);
+		
+		String checkDocId = uri;
+		
+		DocumentDescriptor docExist;
+		
+		docExist = docMgr.exists(checkDocId);
+		return docExist;
+	}*/
+			
+	/**
+	 * Read metadata from document
+	 * @param client
+	 * @param uri
+	 * @param type
+	 * @return
+	 */
+	public DocumentMetadataHandle readMetadataFromDocument(DatabaseClient client, String uri, String type)
+	{
+		// create doc manager
+		DocumentManager docMgr = null;
+		docMgr = documentManagerSelector(client, docMgr, type);		
+		
+		// create handle
+		DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+		
+		// create doc id
+		String readDocId = uri;
+		System.out.println("Read metadata from " + readDocId);
+
+		// read metadata
+		docMgr.readMetadata(readDocId, readMetadataHandle);
+		
+		return readMetadataHandle;
+	}
+	
+	/**
+	 * Set query option in XML
+	 * @param client
+	 * @param queryOptionName
+	 * @throws FileNotFoundException
+	 */
+	public void setQueryOption(DatabaseClient client, String queryOptionName) throws FileNotFoundException
+	{
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+		
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+			
+		//handle.setFormat(Format.XML);
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		System.out.println("Write " + queryOptionName + " to database");
+	}
+	/**
+	 * Copy Files from One location to Other
+	 * @param Source File
+	 * @param target File
+	 * @param Boolean Value
+	 * @throws FileNotFoundException
+	 */	
+	public void copyWithChannels(File aSourceFile, File aTargetFile, boolean aAppend) {
+	    //log("Copying files with channels.");
+	    //ensureTargetDirectoryExists(aTargetFile.getParentFile());
+	    FileChannel inChannel = null;
+	    FileChannel outChannel = null;
+	    FileInputStream inStream = null;
+	    FileOutputStream outStream = null;
+	    try{
+	      try {
+	        inStream = new FileInputStream(aSourceFile);
+	        inChannel = inStream.getChannel();
+	        outStream = new  FileOutputStream(aTargetFile, aAppend);        
+	        outChannel = outStream.getChannel();
+	        long bytesTransferred = 0;
+	        //defensive loop - there's usually only a single iteration :
+	        while(bytesTransferred < inChannel.size()){
+	          bytesTransferred += inChannel.transferTo(0, inChannel.size(), outChannel);
+	        }
+	      }
+	      finally {
+	        //being defensive about closing all channels and streams 
+	        if (inChannel != null) inChannel.close();
+	        if (outChannel != null) outChannel.close();
+	        if (inStream != null) inStream.close();
+	        if (outStream != null) outStream.close();
+	      }
+	    }
+	    catch (FileNotFoundException ex){
+	      System.out.println("File not found: " + ex);
+	    }
+	    catch (IOException ex){
+	      System.out.println(ex);
+	    }
+	  }
+	/**
+	 * Set query option in JSON
+	 * @param client
+	 * @param queryOptionName
+	 * @throws FileNotFoundException
+	 */
+	public void setJSONQueryOption(DatabaseClient client, String queryOptionName) throws FileNotFoundException
+	{
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create handle to write option in xml
+		ReaderHandle handle = new ReaderHandle();
+		handle.setFormat(Format.JSON);
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+		
+		// write the query options to the database in xml
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		System.out.println("Write " + queryOptionName + " to database");	
+		
+		// read query option in json
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		
+		String jsonQueryOption = readHandle.get();
+		
+		// create handle to write back option in json
+		String queryOptionNameJson = queryOptionName.replaceAll(".xml", ".json");
+		StringHandle writeHandle = new StringHandle();
+		writeHandle.set(jsonQueryOption);
+		writeHandle.setFormat(Format.JSON);
+		optionsMgr.writeOptions(queryOptionNameJson, writeHandle);
+		System.out.println("Write " + queryOptionNameJson + " to database");
+	}
+	
+	public SearchHandle runSearch(DatabaseClient client, String queryOptionName, String criteria)
+	{
+		// create a manager for searching
+		QueryManager queryMgr = client.newQueryManager();
+
+		// create a search definition
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria(criteria);
+		
+		// create a handle for the search results
+		SearchHandle resultsHandle = new SearchHandle();
+
+		// run the search
+		return queryMgr.search(querydef, resultsHandle);
+	
+	}
+	
+	public String returnSearchResult(SearchHandle resultsHandle)
+	{
+		String matchedDoc = ""; 
+		
+		// iterate over the result documents
+		MatchDocumentSummary[] docSummaries = resultsHandle.getMatchResults();
+		for (MatchDocumentSummary docSummary: docSummaries) {
+			String uri = docSummary.getUri();
+
+			// iterate over the match locations within a result document
+			MatchLocation[] locations = docSummary.getMatchLocations();
+		        matchedDoc = matchedDoc + "|" + "Matched "+locations.length+" locations in "+uri;
+		}
+		return matchedDoc;
+	}
+
+	/**
+	 * Get the size of binary file
+	 * @param fileRead
+	 * @return
+	 * @throws IOException
+	 */
+	public int getBinarySize(InputStream fileRead) throws IOException
+	{
+		ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+		byte[] b = new byte[1000];
+		int len = 0;
+		while (((len=fileRead.read(b)) != -1)) {
+			baos.write(b, 0, len);
+		}
+		
+		byte[] buf = baos.toByteArray();
+		return buf.length;
+	}
+	
+	/**
+	 * Get document properties in string
+	 * @param properties
+	 * @return
+	 */
+	public String getDocumentPropertiesString(DocumentProperties properties)
+	{
+	    Set setProperties = properties.entrySet(); 
+	    Iterator iProperties = setProperties.iterator(); 
+	    String stringProperties = "size:" + properties.size() + "|";
+	    while(iProperties.hasNext()) 
+	    {
+	    	Map.Entry meProperties = (Map.Entry)iProperties.next();
+	    	stringProperties = stringProperties + meProperties.getKey() + ":" + meProperties.getValue() + "|";
+	    }
+	    
+	    return stringProperties;
+	}
+	
+	/**
+	 * Get document permissions in string
+	 * @param permissions
+	 * @return
+	 */
+	public String getDocumentPermissionsString(DocumentPermissions permissions)
+	{
+	    Set setPermissions = permissions.entrySet(); 
+	    Iterator iPermissions = setPermissions.iterator(); 
+	    String stringPermissions = "size:" + permissions.size() + "|";
+	    while(iPermissions.hasNext()) 
+	    {
+	    	Map.Entry mePermissions = (Map.Entry)iPermissions.next();
+	    	stringPermissions = stringPermissions + mePermissions.getKey() + ":" + mePermissions.getValue() + "|";
+	    }
+	    
+	    return stringPermissions;
+	}
+	
+	/**
+	 * Get document collections in string
+	 * @param collections
+	 * @return
+	 */
+	public String getDocumentCollectionsString(DocumentCollections collections)
+	{
+	    Iterator iCollections = collections.iterator();
+	    String stringCollections = "size:" + collections.size() + "|";
+	    while (iCollections.hasNext()) {
+	        // Get element
+	        Object element = iCollections.next();
+	        stringCollections = stringCollections + element + "|";
+	    }
+	    
+	    return stringCollections;
+	}	
+	
+	/**
+	 * Function to select and create document manager based on the type
+	 * @param client
+	 * @param docMgr
+	 * @param type
+	 * @return
+	 */
+	public DocumentManager documentManagerSelector(DatabaseClient client, DocumentManager docMgr, String type)
+	{
+		// create doc manager
+		if(type == "XML")
+		{
+			docMgr = client.newXMLDocumentManager();
+		}
+		else if(type == "Text")
+		{	
+			docMgr = client.newTextDocumentManager();
+		}
+		else if(type == "JSON")
+		{	
+			docMgr = client.newJSONDocumentManager();
+		}
+		else if(type == "Binary")
+		{	
+			docMgr = client.newBinaryDocumentManager();
+		}
+		else if (type == "JAXB") {
+			docMgr = client.newXMLDocumentManager();
+		}
+		else 
+		{ 
+	
+			System.out.println("Invalid type");
+		}
+		
+		return docMgr;
+	}
+	
+	/**
+	 * Return search report based on element names
+	 * @param resultDoc
+	 * @param tagNames
+	 */
+	public String returnSearchReport(Document resultDoc, String[] tagNames)
+	{
+		String sConcat = "";
+		Element root = resultDoc.getDocumentElement();
+		NodeList searchResultNodeList = root.getElementsByTagName("search:result");
+		for(int i = 0; i < searchResultNodeList.getLength(); i++)
+		{	
+			Element attributeElement = (Element) searchResultNodeList.item(i);
+			String attributeValue = attributeElement.getAttribute("uri");
+					
+			sConcat = sConcat + "";
+			for(String tagName : tagNames)
+			{
+				NodeList elementNodeList = root.getElementsByTagName(tagName);
+				Node elementNode = elementNodeList.item(i);
+				String elementValue = elementNode.getTextContent();
+				sConcat = sConcat + "<" + tagName + ">" + elementValue + "";
+			}
+			sConcat = sConcat + "";
+		}
+		NodeList searchReportList = root.getElementsByTagName("search:report");
+		Node searchReportNode = searchReportList.item(0);
+		String searchReportValue = searchReportNode.getTextContent();
+		sConcat = sConcat + "" + searchReportValue + "";
+		
+		return sConcat;
+	}
+	
+	/**
+	 * Get the expected XML document
+	 * @param filename
+	 * @return
+	 * @throws ParserConfigurationException
+	 * @throws SAXException
+	 * @throws IOException
+	 */
+	public Document expectedXMLDocument(String filename) throws ParserConfigurationException, SAXException, IOException
+	{
+		// get xml document for expected result
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document expectedDoc = docBuilder.parse(new File("src/test/java/com/marklogic/javaclient/data/" + filename));
+		return expectedDoc;
+	}
+	
+	/**
+	 * Get the expected JSON document
+	 * @param filename
+	 * @return
+	 * @throws JsonParseException
+	 * @throws IOException
+	 */
+	public JsonNode expectedJSONDocument(String filename) throws JsonParseException, IOException
+	{
+		// get json document for expected result
+		ObjectMapper mapper = new ObjectMapper();
+		JsonFactory jfactory = new JsonFactory();
+		JsonParser jParser = jfactory.createJsonParser(new File("src/test/java/com/marklogic/javaclient/data/" + filename));
+		JsonNode expectedDoc = mapper.readTree(jParser);		
+		return expectedDoc;
+	}
+	
+	/**
+	 * Get the expected JSON query option
+	 * @param filename
+	 * @return
+	 * @throws JsonParseException
+	 * @throws IOException
+	 */
+	public JsonNode expectedJSONQueryOption(String filename) throws JsonParseException, IOException
+	{
+		// get json document for expected result
+		ObjectMapper mapper = new ObjectMapper();
+		JsonFactory jfactory = new JsonFactory();
+		JsonParser jParser = jfactory.createJsonParser(new File("src/test/java/com/marklogic/javaclient/queryoptions/" + filename));
+		JsonNode expectedDoc = mapper.readTree(jParser);		
+		return expectedDoc;
+	}
+	
+	/**
+	 * Get the expected xml key
+	 * @param filename
+	 * @return
+	 * @throws ParserConfigurationException
+	 * @throws SAXException
+	 * @throws IOException
+	 */
+	public Document expectedXMLKey(String filename) throws ParserConfigurationException, SAXException, IOException
+	{
+		// get xml document for expected result
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document expectedDoc = docBuilder.parse(new File("src/test/java/com/marklogic/javaclient/keys/" + filename));
+		return expectedDoc;
+	}
+	
+	/**
+	 * Get the metadata xml
+	 * @param filename
+	 * @return
+	 * @throws ParserConfigurationException
+	 * @throws SAXException
+	 * @throws IOException
+	 */
+	public Document getXMLMetadata(String filename) throws ParserConfigurationException, SAXException, IOException
+	{
+		// get xml document for expected result
+		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+		Document metadataDoc = docBuilder.parse(new File("src/test/java/com/marklogic/javaclient/metadata/" + filename));
+		return metadataDoc;
+	}
+	
+	/**
+	 * Convert string to xml document. Used on actual read content for XML comparison
+	 * @param readContent
+	 * @return
+	 * @throws ParserConfigurationException
+	 * @throws SAXException
+	 * @throws IOException
+	 */
+	public Document convertStringToXMLDocument(String readContent) throws ParserConfigurationException, SAXException, IOException
+	{
+		// convert actual string to xml doc
+	    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+	    DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+	    InputSource is = new InputSource( new StringReader( readContent ) );
+	    Document readDoc = docBuilder.parse( is );
+	    
+	    return readDoc;
+	}
+	/**
+	 * Convert XMLEventReader To String
+	 * @param XMLEventReader
+	 * @return String
+	 * @throws XMLStreamException, TransformerException, IOException, ParserConfigurationException, SAXException
+	 */
+	
+	public String convertXMLEventReaderToString(XMLEventReader fileRead) throws IOException, TransformerException, XMLStreamException
+	{
+	    //BufferedReader br = (BufferedReader) fileRead;
+String readContent = "";
+String line = null;
+while (fileRead.hasNext())
+		readContent = readContent +fileRead.next();
+
+return readContent;	    
+
+}
+	/**
+	 * Convert XMLStreamReader To String
+	 * @param XMLStreamReader
+	 * @return String
+	 * @throws XMLStreamException, TransformerException, IOException, ParserConfigurationException, SAXException
+	 */
+	public String convertXMLStreamReaderToString(XMLStreamReader reader) throws XMLStreamException, TransformerException, IOException, ParserConfigurationException, SAXException {
+        String str = null;
+		while (reader.hasNext())
+		{
+		    reader.next();
+		    int a = reader.getEventType();
+		    if (reader.hasText())
+		    	if ( reader.getText() != "null" )
+		        str =str + reader.getText().trim();
+		}
+		return str;
+	}
+	/**
+	 * Convert xml document to string. Useful for debugging purpose
+	 * @param readContent
+	 * @return
+	 * @throws TransformerException
+	 */
+	public String convertXMLDocumentToString(Document readContent) throws TransformerException
+	{
+		TransformerFactory tf = TransformerFactory.newInstance();
+		Transformer transformer = tf.newTransformer();
+		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+		StringWriter writer = new StringWriter();
+		transformer.transform(new DOMSource(readContent), new StreamResult(writer));
+		String output = writer.getBuffer().toString();
+		return output;
+	}
+	
+//	public String convertJAXBToString(JAXB readfile) throws JAXBException{
+//		String xml = null;
+//		readfile.marshal(readfile, xml);
+//		System.out.println(xml);
+//		return xml;
+//		
+//	}
+	/**
+	 * Convert inputstream to string. Used on InputStreamHandle
+	 * @param fileRead
+	 * @return
+	 * @throws IOException 
+	 */
+	public String convertInputStreamToString(InputStream fileRead) throws IOException
+	{
+		int ch;
+		StringBuffer strContent = new StringBuffer("");
+		
+		while((ch = fileRead.read()) != -1)
+			strContent.append((char)ch);
+			
+		fileRead.close();
+		
+		String readContent = strContent.toString();
+		return readContent;
+	}
+	/**
+	 * Convert inputsource to string. Used on InputSourceHandle
+	 * @param fileRead
+	 * @return
+	 * @throws IOException 
+	 * @throws TransformerException 
+	 */
+	public String convertInputSourceToString(InputSource fileRead) throws IOException, TransformerException
+	{
+		SAXSource saxsrc = new SAXSource(fileRead);
+		TransformerFactory tf = TransformerFactory.newInstance();
+		Transformer transformer = tf.newTransformer();
+		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+		StringWriter writer = new StringWriter();
+		transformer.transform(saxsrc, new StreamResult(writer));
+		String output = writer.getBuffer().toString();
+		return output;
+	}
+	
+	/**
+	 * Convert source to string. Used on SourceHandle
+	 * @param fileRead
+	 * @return
+	 * @throws IOException 
+	 * @throws TransformerException 
+	 */
+	public String convertSourceToString(Source reader) throws IOException, TransformerException
+	{
+		StringWriter stringWriter = new StringWriter();
+		Result result = new StreamResult(stringWriter);
+		TransformerFactory factory = TransformerFactory.newInstance();
+		Transformer transformer = factory.newTransformer();
+		transformer.transform(reader, result);
+		String str = stringWriter.getBuffer().toString();
+		return str;
+
+	}
+	/**
+	 * Convert reader to string. Used on ReaderHandle
+	 * @param fileRead
+	 * @return
+	 * @throws IOException
+	 */
+	public String convertReaderToString(Reader fileRead) throws IOException
+	{
+	    BufferedReader br = new BufferedReader(fileRead);
+	    String readContent = "";
+	    String line = null;
+	    while ((line = br.readLine()) != null)
+	    		readContent = readContent + line;
+	    
+	    br.close();
+	    
+	    return readContent;	    
+	}
+	
+	/**
+	 * Convert file to string. Used on FileHandle
+	 * @param fileRead
+	 * @return
+	 * @throws FileNotFoundException
+	 */
+	public String convertFileToString(File fileRead) throws FileNotFoundException
+	{
+	    Scanner scanner = new Scanner(fileRead).useDelimiter("\\Z");
+	    String readContent = scanner.next();
+	    scanner.close();
+	    
+	    return readContent;
+	}
+	
+	/**
+	 * Load geo data for geo spatial tests
+	 * @throws FileNotFoundException
+	 */
+	public void loadGeoData() throws FileNotFoundException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(int i = 1; i <= 24; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		//release client
+		client.release();
+	}
+/*
+ * {
+  "collections": [
+    "shapes",
+    "squares"
+  ],
+  "permissions": [
+    {
+      "role-name": "hadoop-user-read",
+      "capabilities": [
+        "read"
+      ]
+    }
+  ],
+  "properties": {
+    "myprop": "this is my prop",
+    "myotherprop": "this is my other prop"
+  },
+  "quality": 0
+}
+ */
+  public JsonNode constructJSONPropertiesMetadata(Map prop){
+	  ObjectMapper mapper = new ObjectMapper();
+	  ObjectNode mainNode = mapper.createObjectNode();
+	  ObjectNode cNode = mapper.createObjectNode();
+	 
+	   Iterator keys = prop.keySet().iterator();
+	   while(keys.hasNext())
+	   {
+		   String keyvalue = keys.next().toString();
+		   cNode.put(keyvalue,prop.get(keyvalue).toString());
+	   }
+	   mainNode.set("properties", cNode);
+	  return (mainNode);
+  }
+  public JsonNode constructJSONCollectionMetadata(String...col){
+	  ObjectMapper mapper= new ObjectMapper();
+		 ObjectNode mNode = mapper.createObjectNode();
+		 ArrayNode aNode = mapper.createArrayNode();
+		 
+		 for(String c : col){
+			 aNode.add(c);
+		 }
+		 mNode.withArray("collections").addAll(aNode);
+		 return mNode;
+  }
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/ConnectedRESTQA.java b/test-complete/src/test/java/com/marklogic/javaclient/ConnectedRESTQA.java
new file mode 100644
index 000000000..08a6d382a
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/ConnectedRESTQA.java
@@ -0,0 +1,1261 @@
+package com.marklogic.javaclient;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.util.*;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.client.entity.*;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import java.net.InetAddress;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public abstract class ConnectedRESTQA {
+	
+	/**
+	 * Use Rest call to create a database.
+	 *  @param dbName
+	 */
+	
+	public static void createDB(String dbName)	{
+	try {	
+		
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/databases?format=json");
+			String JSONString = "[{\"name\":\""+ dbName + "\"}]";
+
+       post.addHeader("Content-type", "application/json");
+		    post.setEntity( new StringEntity(JSONString));
+		
+		
+			HttpResponse response = client.execute(post);
+			HttpEntity respEntity = response.getEntity();
+
+		    if (respEntity != null) {
+		        // EntityUtils to get the response content
+		        String content =  EntityUtils.toString(respEntity);
+		        System.out.println(content);
+		    }
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+	}
+		/*
+	 * 
+	 */
+	public static void createForest(String fName,String dbName)	{
+	try{
+		DefaultHttpClient client = new DefaultHttpClient();
+		client.getCredentialsProvider().setCredentials(
+				new AuthScope("localhost", 8002),
+				new UsernamePasswordCredentials("admin", "admin"));
+		HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/forests?format=json");
+		String hName =InetAddress.getLocalHost().getCanonicalHostName().toLowerCase();
+		String JSONString = 
+				"{\"database\":\""+ 
+				dbName + 
+				"\",\"forest-name\":\""+
+				fName+
+				"\",\"host\":\""+hName+"\"}" 
+								;
+//		System.out.println(JSONString);
+		post.addHeader("Content-type", "application/json");
+		post.setEntity(new StringEntity(JSONString));
+	
+		HttpResponse response = client.execute(post);
+		HttpEntity respEntity = response.getEntity();
+
+		if (respEntity != null) {
+		// EntityUtils to get the response content
+		String content =  EntityUtils.toString(respEntity);
+		System.out.println(content);
+		}
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+	}
+	/*
+	 * creating forests on different hosts
+	 */
+	public static void createForestonHost(String fName,String dbName,String hName)	{
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+			HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/forests?format=json");
+			String JSONString = 
+					"{\"database\":\""+ 
+					dbName + 
+					"\",\"forest-name\":\""+
+					fName+
+					"\",\"host\":\""+hName+"\"}" 
+									;
+//			System.out.println(JSONString);
+			post.addHeader("Content-type", "application/json");
+			post.setEntity(new StringEntity(JSONString));
+		
+			HttpResponse response = client.execute(post);
+			HttpEntity respEntity = response.getEntity();
+
+			if (respEntity != null) {
+			// EntityUtils to get the response content
+			String content =  EntityUtils.toString(respEntity);
+			System.out.println(content);
+			}
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+		}
+		
+	public static void assocRESTServer(String restServerName,String dbName,int restPort)	{
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpPost post = new HttpPost("http://localhost:8002"+ "/v1/rest-apis?format=json");
+//			
+			String JSONString = 
+					"{ \"rest-api\": {\"database\":\""+ 
+					dbName + 
+					"\",\"name\":\""+
+					restServerName +
+					"\",\"port\":\""+
+					restPort+
+					"\"}}";
+//			System.out.println(JSONString);		
+			post.addHeader("Content-type", "application/json");
+			post.setEntity(new StringEntity(JSONString));
+		
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+
+			    if (respEntity != null) {
+			        // EntityUtils to get the response content
+			        String content =  EntityUtils.toString(respEntity);
+			        System.out.println(content);
+			    }
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+		}
+/*
+ * Creating RESTServer With default content and module database
+ */
+	public static void createRESTServerWithDB(String restServerName,int restPort)	{
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+			HttpPost post = new HttpPost("http://localhost:8002"+ "/v1/rest-apis?format=json");
+//			
+			String JSONString = 
+					"{ \"rest-api\": {\"name\":\""+
+					restServerName +
+					"\",\"port\":\""+
+					restPort+
+					"\"}}";
+			//System.out.println(JSONString);		
+			post.addHeader("Content-type", "application/json");
+			post.setEntity(new StringEntity(JSONString));
+		
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+
+			    if (respEntity != null) {
+			        // EntityUtils to get the response content
+			        String content =  EntityUtils.toString(respEntity);
+			        System.out.println(content);
+			    }
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+		}
+
+	/*
+	 * This function creates database,forests and REST server independently and attaches the database to the rest server
+	 * 
+	 */
+	public static void setupJavaRESTServer(String dbName, String fName, String restServerName, int restPort)throws Exception{
+		 
+			createDB(dbName); 
+			createForest(fName,dbName); 
+			Thread.sleep(1500); 
+	        assocRESTServer(restServerName, dbName,restPort);
+	        createRESTUser("rest-admin","x","rest-admin");
+	        createRESTUser("rest-writer","x","rest-writer");
+	        createRESTUser("rest-reader","x","rest-reader");
+	}
+	/*
+	 * This function creates a REST server with default content DB, Module DB
+	 */
+
+	 public static void createRESTUser(String usrName, String pass, String... roleNames ){
+	    	try{
+				DefaultHttpClient client = new DefaultHttpClient();
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+			HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/users/"+usrName);
+			HttpResponse resp = client.execute(getrequest);
+			 
+			if( resp.getStatusLine().getStatusCode() == 200)
+             {
+				 System.out.println("User already exist");
+             }
+			 else {
+				 System.out.println("User dont exist");
+				 client = new DefaultHttpClient();
+					client.getCredentialsProvider().setCredentials(
+							new AuthScope("localhost", 8002),
+							new UsernamePasswordCredentials("admin", "admin"));
+						
+		 	ObjectMapper mapper = new ObjectMapper();
+			ObjectNode mainNode = mapper.createObjectNode();
+//			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			mainNode.put("name",usrName);
+			mainNode.put("description", "user discription");
+			mainNode.put("password", pass);
+			for(String rolename: roleNames)
+			childArray.add(rolename);
+			mainNode.withArray("role").addAll(childArray);
+			//System.out.println(type + mainNode.path("range-element-indexes").path("range-element-index").toString());
+				System.out.println(mainNode.toString());
+				HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/users?format=json");
+				post.addHeader("Content-type", "application/json");
+				post.setEntity(new StringEntity(mainNode.toString()));
+			
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+               if( response.getStatusLine().getStatusCode() == 400)
+               {
+             	  System.out.println("User already exist");
+               }
+               else if (respEntity != null) {
+				// EntityUtils to get the response content
+				String content =  EntityUtils.toString(respEntity);
+				System.out.println(content);
+				}
+               else {System.out.print("No Proper Response");}
+			 }
+				}catch (Exception e) {
+				    // writing error to Log
+				    e.printStackTrace();
+				}
+	    }
+	 
+	 /*
+	  *  "permission": [
+    {
+      "role-name": "dls-user",
+      "capability": "read"
+    }
+	  */
+
+	 public static ObjectNode getPermissionNode(String roleName, DocumentMetadataHandle.Capability... cap){
+		 ObjectMapper mapper= new ObjectMapper();
+		 ObjectNode mNode = mapper.createObjectNode();
+		 ArrayNode aNode = mapper.createArrayNode();
+		 
+		 for(DocumentMetadataHandle.Capability c : cap){
+			 ObjectNode roleNode =mapper.createObjectNode();
+			 roleNode.put("role-name",roleName);
+			 roleNode.put("capability", c.toString().toLowerCase());
+		 	 aNode.add(roleNode);
+		 }
+		 mNode.withArray("permission").addAll(aNode);
+		 return mNode;
+	 }
+	 
+	 /*
+	  * "collection":
+[
+"dadfasd",
+"adfadsfads"
+]
+	  */
+	 public static ObjectNode getCollectionNode(String... collections){
+		 ObjectMapper mapper= new ObjectMapper();
+		 ObjectNode mNode = mapper.createObjectNode();
+		 ArrayNode aNode = mapper.createArrayNode();
+		 
+		 for(String c : collections){
+			 aNode.add(c);
+		 }
+		 mNode.withArray("collection").addAll(aNode);
+		 return mNode;
+	 }
+	 
+	 public static void createRESTUserWithPermissions(String usrName, String pass,ObjectNode perm,ObjectNode colections, String... roleNames ){
+	    	try{
+				DefaultHttpClient client = new DefaultHttpClient();
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+			HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/users/"+usrName);
+			HttpResponse resp = client.execute(getrequest);
+			 
+			if( resp.getStatusLine().getStatusCode() == 200)
+          {
+				 System.out.println("User already exist");
+          }
+			 else {
+				 System.out.println("User dont exist");
+				 client = new DefaultHttpClient();
+					client.getCredentialsProvider().setCredentials(
+							new AuthScope("localhost", 8002),
+							new UsernamePasswordCredentials("admin", "admin"));
+						
+		 	ObjectMapper mapper = new ObjectMapper();
+			ObjectNode mainNode = mapper.createObjectNode();
+//			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			mainNode.put("name",usrName);
+			mainNode.put("description", "user discription");
+			mainNode.put("password", pass);
+			for(String rolename: roleNames)
+			childArray.add(rolename);
+			mainNode.withArray("role").addAll(childArray);
+			mainNode.setAll(perm);
+			mainNode.setAll(colections);
+			//System.out.println(type + mainNode.path("range-element-indexes").path("range-element-index").toString());
+				System.out.println(mainNode.toString());
+				HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/users?format=json");
+				post.addHeader("Content-type", "application/json");
+				post.setEntity(new StringEntity(mainNode.toString()));
+			
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+            if( response.getStatusLine().getStatusCode() == 400)
+            {
+          	  System.out.println("Bad User creation request");
+            }
+            else if (respEntity != null) {
+				// EntityUtils to get the response content
+				String content =  EntityUtils.toString(respEntity);
+				System.out.println(content);
+				}
+            else {System.out.print("No Proper Response");}
+			 }
+				}catch (Exception e) {
+				    // writing error to Log
+				    e.printStackTrace();
+				}
+	    }
+
+    public static void deleteRESTUser(String usrName){
+	try{
+		DefaultHttpClient client = new DefaultHttpClient();
+
+		client.getCredentialsProvider().setCredentials(
+				new AuthScope("localhost", 8002),
+				new UsernamePasswordCredentials("admin", "admin"));
+		
+		HttpDelete delete = new HttpDelete("http://localhost:8002/manage/v2/users/"+usrName);
+		
+			HttpResponse response = client.execute(delete);
+		if(response.getStatusLine().getStatusCode()== 202){
+						Thread.sleep(3500);
+		}
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+	
+}
+	 
+	 public static void setupJavaRESTServerWithDB( String restServerName, int restPort)throws Exception{		 
+        createRESTServerWithDB(restServerName, restPort);
+        createRESTUser("rest-admin","x","rest-admin");
+        createRESTUser("rest-writer","x","rest-writer");
+        createRESTUser("rest-reader","x","rest-reader"); 
+}
+/*
+ * This function deletes the REST appserver along with attached content database and module database
+ */
+	
+	
+	public static void deleteRESTServerWithDB(String restServerName)	{
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpDelete delete = new HttpDelete("http://localhost:8002/v1/rest-apis/"+restServerName+"?include=content&include=modules");
+			
+				HttpResponse response = client.execute(delete);
+			if(response.getStatusLine().getStatusCode()== 202){
+							Thread.sleep(3500);
+			}
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+		}
+	/*
+	 * 
+	 */
+	public static void deleteRESTServer(String restServerName)	{
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpDelete delete = new HttpDelete("http://localhost:8002/v1/rest-apis/"+restServerName+"&include=modules");
+			HttpResponse response = client.execute(delete);
+			
+			if(response.getStatusLine().getStatusCode()== 202){
+				Thread.sleep(3500);
+				waitForServerRestart();
+			}
+			else System.out.println("Server response "+response.getStatusLine().getStatusCode());
+			}catch (Exception e) {
+			    // writing error to Log
+				System.out.println("Inside Deleting Rest server is throwing an error");
+			    e.printStackTrace();
+			}
+		}
+	public static void detachForest(String dbName, String fName){
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/forests/"+fName);
+//			
+			List urlParameters = new ArrayList();
+			urlParameters.add(new BasicNameValuePair("state", "detach"));
+			urlParameters.add(new BasicNameValuePair("database", dbName));
+			
+			post.setEntity(new UrlEncodedFormEntity(urlParameters));
+						
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+
+			    if (respEntity != null) {
+			        // EntityUtils to get the response content
+			        String content =  EntityUtils.toString(respEntity);
+			        System.out.println(content);
+			    }
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}	
+	}
+	/*
+	 * Deleting a forest is a HTTP Delete request
+	 * 
+	 */
+	public static void deleteForest(String fName){
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpDelete delete = new HttpDelete("http://localhost:8002/manage/v2/forests/"+fName+"?level=full");
+			client.execute(delete);
+			
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+	}
+/*
+ * Deleting Database
+ * 
+ */
+	public static void deleteDB(String dbName){
+	try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+
+			HttpDelete delete = new HttpDelete("http://localhost:8002/manage/v2/databases/"+dbName);
+			client.execute(delete);
+			
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+	}
+	
+	public static void clearDB(int port){
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", port),
+					new UsernamePasswordCredentials("admin", "admin"));
+			String uri = "http://localhost:"+port+"/v1/search/";
+			HttpDelete delete = new HttpDelete(uri);
+			client.execute(delete);
+			
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+	}
+	public static void waitForServerRestart()
+	{
+		try{
+		int count = 0;
+		while(count <20){
+		DefaultHttpClient client = new DefaultHttpClient();
+		client.getCredentialsProvider().setCredentials(
+				new AuthScope("localhost", 8001),
+				new UsernamePasswordCredentials("admin", "admin"));
+		
+			count++;
+			try{
+		HttpGet getrequest = new HttpGet("http://localhost:8001/admin/v1/timestamp");
+		HttpResponse response = client.execute(getrequest);
+		if(response.getStatusLine().getStatusCode() == 503){Thread.sleep(4000);}
+		else if(response.getStatusLine().getStatusCode() == 200){
+				break;
+		}
+		else {
+			System.out.println("Waiting for response from server, Trial :"+response.getStatusLine().getStatusCode()+count);
+			Thread.sleep(2000);
+		}
+			}catch(Exception e){Thread.sleep(2000);}
+		}
+	}catch(Exception e){
+		System.out.println("Inside wait for server restart is throwing an error");
+	                e.printStackTrace();
+	        }
+	}
+	/*
+	 * This function deletes rest server first and deletes forests and databases in separate calls
+	 */
+	public static void tearDownJavaRESTServer(String dbName, String [] fNames, String restServerName) throws Exception{
+			
+		try{
+			deleteRESTServer(restServerName); 
+		}catch(Exception e){
+			System.out.println("From Deleting Rest server called funnction is throwing an error");
+			e.printStackTrace(); 
+		}
+		waitForServerRestart(); 
+		try{
+			for(int i = 0; i < fNames.length; i++){
+				detachForest(dbName, fNames[i]); 
+			}
+		}catch(Exception e){
+	                e.printStackTrace();
+	        }
+
+		try{
+			for(int i = 0; i < fNames.length; i++){
+				deleteForest(fNames[i]); 
+			}
+		}catch(Exception e){
+	                e.printStackTrace();
+	        }
+		
+			deleteDB(dbName); 
+	    }
+	
+	/*
+	 * This function deletes rest server along with default forest and database 
+	 */
+	public static void tearDownJavaRESTServerWithDB(String restServerName) throws Exception{
+			
+		try{
+			deleteRESTServerWithDB(restServerName); 
+		}catch(Exception e){
+			e.printStackTrace(); 
+		}
+		Thread.sleep(6000); 
+		 
+	    }
+	
+	/*
+	 * 
+	 * setting up AppServices configurations 
+	 * setting up database properties whose value is string
+	 */
+	public static void setDatabaseProperties(String dbName,String prop,String propValue ) throws IOException{
+		InputStream jsonstream=null;
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+			HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+			HttpResponse response1 = client.execute(getrequest);
+			jsonstream =response1.getEntity().getContent();
+			JsonNode jnode= new ObjectMapper().readTree(jsonstream);
+            if(!jnode.isNull()){       	
+            	((ObjectNode)jnode).put(prop, propValue);
+//            System.out.println(jnode.toString()+"\n"+ response1.getStatusLine().getStatusCode());
+            HttpPut put = new HttpPut("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+    		put.addHeader("Content-type", "application/json");
+    		put.setEntity(new StringEntity(jnode.toString()));
+    	
+    		HttpResponse response2 = client.execute(put);
+    		HttpEntity respEntity = response2.getEntity();
+    		if(respEntity != null){
+    			String content =  EntityUtils.toString(respEntity);
+    			System.out.println(content);
+    		}
+    		}
+            else{
+            	System.out.println("REST call for database properties returned NULL ");
+            }
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+		finally{
+			if(jsonstream == null){}
+			else{
+				jsonstream.close();
+			}
+			}
+		}
+			
+	public static void setDatabaseProperties(String dbName,String prop,boolean propValue ) throws IOException{
+		InputStream jsonstream=null;
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+			HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+			HttpResponse response1 = client.execute(getrequest);
+			jsonstream =response1.getEntity().getContent();
+			JsonNode jnode= new ObjectMapper().readTree(jsonstream);
+            if(!jnode.isNull()){       	
+         	((ObjectNode)jnode).put(prop, propValue)   ;
+//            System.out.println(jnode.toString()+"\n"+ response1.getStatusLine().getStatusCode());
+            HttpPut put = new HttpPut("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+    		put.addHeader("Content-type", "application/json");
+    		put.setEntity(new StringEntity(jnode.toString()));
+    	
+    		HttpResponse response2 = client.execute(put);
+    		HttpEntity respEntity = response2.getEntity();
+    		if(respEntity != null){
+    			String content =  EntityUtils.toString(respEntity);
+    			System.out.println(content);
+    		}
+    		}
+            else{
+            	System.out.println("REST call for database properties returned NULL ");
+            }
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+		finally{
+			if(jsonstream == null){}
+			else{
+				jsonstream.close();
+			}
+			}
+		}
+	
+	/*
+	 * This Method takes the root property name and object node under it 
+	 * if root propname exist and equals to null then it just add the object node under root property name else if it has an existing sub property name then it adds 
+	 * elements to that array 
+	 */
+	public static void setDatabaseProperties(String dbName,String propName, ObjectNode objNode ) throws IOException{
+		InputStream jsonstream=null;
+		try{
+			DefaultHttpClient client = new DefaultHttpClient();
+			client.getCredentialsProvider().setCredentials(
+					new AuthScope("localhost", 8002),
+					new UsernamePasswordCredentials("admin", "admin"));
+			HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+			HttpResponse response1 = client.execute(getrequest);
+			jsonstream =response1.getEntity().getContent();
+			ObjectMapper mapper = new ObjectMapper();
+			JsonNode jnode= mapper.readTree(jsonstream);
+            if(!jnode.isNull()){
+            	
+            	if(!jnode.has(propName)){
+            		((ObjectNode)jnode).putArray(propName).addAll(objNode.withArray(propName));
+//            		 System.out.println("when Node is null"+propName + objNode.toString());
+            	}
+            	else{
+            		if(!jnode.path(propName).isArray()){
+            			System.out.println("property is not array");
+            			((ObjectNode)jnode).putAll(objNode);
+            			}
+            		else{
+            			JsonNode member = jnode.withArray(propName);
+            			if(objNode.path(propName).isArray()){
+            			((ArrayNode)member).addAll(objNode.withArray(propName));
+   //            			System.out.println("when Node is not null"+ propName + objNode.withArray(propName).toString());
+            			}
+            		}
+            	}
+            
+            HttpPut put = new HttpPut("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+    		put.addHeader("Content-type", "application/json");
+    		put.setEntity(new StringEntity(jnode.toString()));
+    	
+    		HttpResponse response2 = client.execute(put);
+    		HttpEntity respEntity = response2.getEntity();
+    		if(respEntity != null){
+    			String content =  EntityUtils.toString(respEntity);
+    			System.out.println(content);
+    		}
+    		}
+            else{
+            	System.out.println("REST call for database properties returned NULL \n"+jnode.toString()+"\n"+ response1.getStatusLine().getStatusCode());
+            }
+		}catch (Exception e) {
+		    // writing error to Log
+		    e.printStackTrace();
+		}
+		finally{
+			if(jsonstream == null){}
+			else{
+				jsonstream.close();
+			}
+			}
+		}
+	
+	public static void enableCollectionLexicon(String dbName) throws Exception{
+		setDatabaseProperties(dbName,"collection-lexicon",true );
+	}
+	/*
+	 * "word-lexicons":  [
+      "http:\/\/marklogic.com\/collation\/"
+    ]
+  }
+	 */
+	public static void enableWordLexicon(String dbName) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		childArray.add("http://marklogic.com/collation/");
+		childNode.putArray("word-lexicon").addAll(childArray);
+		setDatabaseProperties(dbName,"word-lexicons",childNode);
+		
+	}
+	public static void enableTrailingWildcardSearches(String dbName) throws Exception{
+		setDatabaseProperties(dbName,"trailing-wildcard-searches",true );
+	}
+	
+	public static void setMaintainLastModified(String dbName,boolean opt) throws Exception{
+		setDatabaseProperties(dbName,"maintain-last-modified",opt);
+	}
+	/*
+	 * This function constructs a range element index with default collation,range-value-positions and invalid values
+	 * 
+	 */
+	public static void addRangeElementIndex(String dbName,  String type, String namespace, String localname) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode mainNode = mapper.createObjectNode();
+	//	ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		ObjectNode childNodeObject = mapper.createObjectNode();
+		childNodeObject.put( "scalar-type", type);
+		childNodeObject.put( "namespace-uri", namespace);
+		childNodeObject.put( "localname", localname);
+		childNodeObject.put( "collation", "");
+		childNodeObject.put("range-value-positions", false);
+		childNodeObject.put("invalid-values", "reject");
+		childArray.add(childNodeObject);		
+		mainNode.putArray("range-element-index").addAll(childArray);
+	//	mainNode.put("range-element-indexes", childNode);
+//		System.out.println(type + mainNode.path("range-element-indexes").path("range-element-index").toString());
+		setDatabaseProperties(dbName,"range-element-index",mainNode);
+		
+	}
+	
+
+	/*
+	 * This is a overloaded function constructs a range element index with default range-value-positions and invalid values
+	 * 
+	 */
+	public static void addRangeElementIndex(String dbName,  String type, String namespace, String localname, String collation) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode mainNode = mapper.createObjectNode();
+	//	ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		ObjectNode childNodeObject = mapper.createObjectNode();
+		childNodeObject.put( "scalar-type", type);
+		childNodeObject.put( "namespace-uri", namespace);
+		childNodeObject.put( "localname", localname);
+		childNodeObject.put( "collation", collation);
+		childNodeObject.put("range-value-positions", false);
+		childNodeObject.put("invalid-values", "reject");
+		childArray.add(childNodeObject);
+		mainNode.putArray("range-element-index").addAll(childArray);
+		
+//		System.out.println(type + mainNode.path("range-element-indexes").path("range-element-index").toString());
+		setDatabaseProperties(dbName,"range-element-index",mainNode);
+		
+	}
+
+	/*
+	 * "scalar-type": "int",
+        "collation": "",
+        "parent-namespace-uri": "",
+        "parent-localname": "test",
+        "namespace-uri": "",
+        "localname": "testAttr",
+        "range-value-positions": false,
+        "invalid-values": "reject"
+	 */
+	
+	public static void addRangeElementAttributeIndex(String dbName, String type, String parentnamespace, String parentlocalname, String namespace, String localname, String collation) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+	//	ObjectNode mainNode = mapper.createObjectNode();
+		ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		ObjectNode childNodeObject = mapper.createObjectNode();
+		childNodeObject.put( "scalar-type", type);
+		childNodeObject.put( "collation", collation);
+		childNodeObject.put( "parent-namespace-uri", parentnamespace);
+		childNodeObject.put( "parent-localname", parentlocalname);
+		childNodeObject.put( "namespace-uri", namespace);
+		childNodeObject.put( "localname", localname);
+		
+		childNodeObject.put("range-value-positions", false);
+		childNodeObject.put("invalid-values", "reject");
+		childArray.add(childNodeObject);
+		childNode.putArray("range-element-attribute-index").addAll(childArray);
+
+	//	mainNode.put("range-element-attribute-indexes", childNode);
+//		System.out.println(type + mainNode.path("range-element-attribute-indexes").path("range-element-attribute-index").toString());
+		setDatabaseProperties(dbName,"range-element-attribute-index",childNode);
+		
+	}
+	/*
+	 * Overloaded function with default collation
+	 */
+	public static void addRangeElementAttributeIndex(String dbName, String type, String parentnamespace, String parentlocalname, String namespace, String localname) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+		//ObjectNode mainNode = mapper.createObjectNode();
+		ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		ObjectNode childNodeObject = mapper.createObjectNode();
+		childNodeObject.put( "scalar-type", type);
+		childNodeObject.put( "collation", "");
+		childNodeObject.put( "parent-namespace-uri", parentnamespace);
+		childNodeObject.put( "parent-localname", parentlocalname);
+		childNodeObject.put( "namespace-uri", namespace);
+		childNodeObject.put( "localname", localname);
+		
+		childNodeObject.put("range-value-positions", false);
+		childNodeObject.put("invalid-values", "reject");
+		childArray.add(childNodeObject);
+		childNode.putArray("range-element-attribute-index").addAll(childArray);
+	//	mainNode.put("range-element-attribute-indexes", childNode);
+//		System.out.println(type + mainNode.path("range-element-attribute-indexes").path("range-element-attribute-index").toString());
+		setDatabaseProperties(dbName,"range-element-attribute-index",childNode);
+		
+	}
+	/*
+	 *  "range-path-indexes": {
+    "range-path-index": [
+      {
+        "scalar-type": "string",
+        "collation": "http:\/\/marklogic.com\/collation\/",
+        "path-expression": "\/Employee\/fn",
+        "range-value-positions": false,
+        "invalid-values": "reject"
+      }
+    ]
+  }
+	 */
+	public static void addRangePathIndex(String dbName, String type, String pathexpr, String collation, String invalidValues) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+//		ObjectNode mainNode = mapper.createObjectNode();
+		ObjectNode childNode = mapper.createObjectNode();
+		ArrayNode childArray = mapper.createArrayNode();
+		ObjectNode childNodeObject = mapper.createObjectNode();
+		childNodeObject.put( "scalar-type", type);
+		childNodeObject.put( "collation", collation);
+		childNodeObject.put( "path-expression", pathexpr);
+		childNodeObject.put("range-value-positions", false);
+		childNodeObject.put("invalid-values", invalidValues);
+		childArray.add(childNodeObject);
+		childNode.putArray("range-path-index").addAll(childArray);
+//		mainNode.put("range-path-indexes", childNode);
+//		System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+		setDatabaseProperties(dbName,"range-path-index",childNode);
+		
+	}
+	 public static void addGeospatialElementIndexes(String dbName,String localname,String namespace,String coordinateSystem,String pointFormat,boolean rangeValuePositions,String invalidValues) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+	//		ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "namespace-uri", namespace);
+			childNodeObject.put( "localname", localname);
+			childNodeObject.put( "coordinate-system", coordinateSystem);
+			childNodeObject.put("range-value-positions", false);
+			childNodeObject.put("invalid-values", invalidValues);
+			childNodeObject.put("point-format",pointFormat);
+			childArray.add(childNodeObject);
+			childNode.putArray("geospatial-element-index").addAll(childArray);
+//			mainNode.put("geospatial-element-indexes", childNode);
+//			System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+			setDatabaseProperties(dbName,"geospatial-element-index",childNode);
+	 }
+	 public static void addGeoSpatialElementChildIndexes(String dbName,String parentNamespaceUri,String parentLocalName,String namespace,String localname,String coordinateSystem,String pointFormat,boolean rangeValuePositions,String invalidValues) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+	//		ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "parent-namespace-uri", parentNamespaceUri);
+			childNodeObject.put( "parent-localname", parentLocalName);
+			childNodeObject.put( "namespace-uri", namespace);
+			childNodeObject.put( "localname", localname);
+			childNodeObject.put( "coordinate-system", coordinateSystem);
+			childNodeObject.put("range-value-positions", false);
+			childNodeObject.put("invalid-values", invalidValues);
+			childNodeObject.put("point-format",pointFormat);
+			childArray.add(childNodeObject);
+			childNode.putArray("geospatial-element-child-index").addAll(childArray);
+//			mainNode.put("geospatial-element-child-indexes", childNode);
+//			System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+			setDatabaseProperties(dbName,"geospatial-element-child-index",childNode);
+	 }
+	 public static void addGeospatialElementPairIndexes(String dbName,String parentNamespaceUri,String parentLocalName,String latNamespace,String latLocalname,String longNamespace,String longLocalname,String coordinateSystem,boolean rangeValuePositions,String invalidValues) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+	//		ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "parent-namespace-uri", parentNamespaceUri);
+			childNodeObject.put( "parent-localname", parentLocalName);
+			childNodeObject.put( "latitude-namespace-uri", latNamespace);
+			childNodeObject.put( "latitude-localname", latLocalname);
+			childNodeObject.put( "longitude-namespace-uri", latNamespace);
+			childNodeObject.put( "longitude-localname", longLocalname);
+			childNodeObject.put( "coordinate-system", coordinateSystem);
+			childNodeObject.put("range-value-positions", false);
+			childNodeObject.put("invalid-values", invalidValues);
+			childArray.add(childNodeObject);
+			childNode.putArray("geospatial-element-pair-index").addAll(childArray);
+//			mainNode.put("geospatial-element-pair-indexes", childNode);
+//			System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+			setDatabaseProperties(dbName,"geospatial-element-pair-index",childNode);
+	 }
+	 public static void addGeospatialElementAttributePairIndexes(String dbName,String parentNamespaceUri,String parentLocalName,String latNamespace,String latLocalname,String longNamespace,String longLocalname,String coordinateSystem,boolean rangeValuePositions,String invalidValues) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+//			ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "parent-namespace-uri", parentNamespaceUri);
+			childNodeObject.put( "parent-localname", parentLocalName);
+			childNodeObject.put( "latitude-namespace-uri", latNamespace);
+			childNodeObject.put( "latitude-localname", latLocalname);
+			childNodeObject.put( "longitude-namespace-uri", latNamespace);
+			childNodeObject.put( "longitude-localname", longLocalname);
+			childNodeObject.put( "coordinate-system", coordinateSystem);
+			childNodeObject.put("range-value-positions", false);
+			childNodeObject.put("invalid-values", invalidValues);
+			childArray.add(childNodeObject);
+			childNode.putArray("geospatial-element-attribute-pair-index").addAll(childArray);
+//			mainNode.put("geospatial-element-attribute-pair-indexes", childNode);
+//			System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+			setDatabaseProperties(dbName,"geospatial-element-attribute-pair-index",childNode);
+	 }
+	 public static void addGeospatialPathIndexes(String dbName,String pathExpression,String coordinateSystem,String pointFormat,boolean rangeValuePositions,String invalidValues) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+		//	ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "path-expression", pathExpression);
+			childNodeObject.put( "coordinate-system", coordinateSystem);
+			childNodeObject.put("range-value-positions", false);
+			childNodeObject.put("invalid-values", invalidValues);
+			childNodeObject.put("point-format",pointFormat);
+			childArray.add(childNodeObject);
+			childNode.putArray("geospatial-path-index").addAll(childArray);
+	//		mainNode.put("geospatial-path-indexes", childNode);
+//			System.out.println(type + mainNode.path("range-path-indexes").path("range-path-index").toString());
+			setDatabaseProperties(dbName,"geospatial-path-index",childNode);
+	 }
+	/*
+	 * Add field will include root and it appends field to an existing fields
+	 * "fields":{
+		"field":[
+					{
+					"field-name": "",
+					"include-root": true,
+					"included-elements": null,
+					"excluded-elements": null
+					}
+					,
+					{
+					"field-name": "para",
+					"include-root": false,
+					"included-elements": null,
+					"excluded-elements": null,
+					"tokenizer-overrides": null
+					}
+				]
+			}
+	 */
+	 public static void addField(String dbName, String fieldName) throws Exception{
+		 	ObjectMapper mapper = new ObjectMapper();
+		//	ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode arrNode = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "field-name", fieldName);
+			childNodeObject.put("field-type", "root");
+			childNodeObject.put( "include-root", true);
+			childNodeObject.putNull( "included-elements");
+			childNodeObject.putNull( "excluded-elements");
+			childNodeObject.putNull( "tokenizer-overrides");
+			arrNode.add(childNodeObject);
+			childNode.putArray("field").addAll(arrNode);
+	//		mainNode.put("fields", childNode);
+// 		   System.out.println("Entered field to make it true");
+			setDatabaseProperties(dbName,"field",childNode);
+		 
+	 }
+	 public static void addFieldExcludeRoot(String dbName, String fieldName) throws Exception{
+		 	ObjectMapper mapper = new ObjectMapper();
+//			ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode arrNode = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "field-name", fieldName);
+			childNodeObject.put( "include-root", false);
+			childNodeObject.putNull( "included-elements");
+			childNodeObject.putNull( "excluded-elements");
+			childNodeObject.putNull( "tokenizer-overrides");
+			arrNode.add(childNodeObject);
+			childNode.putArray("field").addAll(arrNode);
+//			mainNode.put("fields", childNode);
+//			System.out.println( childNode.toString());
+			setDatabaseProperties(dbName,"field",childNode);
+		 
+	 }
+	 public static void   addBuiltInGeoIndex (String dbName)throws Exception {
+	 addGeospatialElementIndexes(dbName,"g-elem-point","","wgs84","point",false,"reject");
+	 addGeoSpatialElementChildIndexes(dbName,"","g-elem-child-parent","","g-elem-child-point","wgs84","point",false,"reject");
+	 addGeospatialElementPairIndexes(dbName,"","g-elem-pair","","lat","","long","wgs84",false,"reject");
+	 addGeospatialElementAttributePairIndexes(dbName,"","g-attr-pair","","lat","","long","wgs84",false,"reject");
+	 addGeospatialPathIndexes(dbName,"/doc/g-elem-point","wgs84","point",false,"ignore");
+	 }
+	 
+/*
+ This method is trying to add include element or exclude elements to the existing fields
+ *
+ */
+	 public static void setDatabaseFieldProperties(String dbName,String field_name, String propName, ObjectNode objNode ) throws IOException{
+			InputStream jsonstream=null;
+			try{
+				DefaultHttpClient client = new DefaultHttpClient();
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+				HttpGet getrequest = new HttpGet("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+				HttpResponse response1 = client.execute(getrequest);
+				jsonstream =response1.getEntity().getContent();
+				ObjectMapper mapper = new ObjectMapper();
+				JsonNode jnode= mapper.readTree(jsonstream);
+	            if(!jnode.isNull()&& jnode.has("field")){
+	            	JsonNode  fieldNode = jnode.withArray("field");
+	            	Iterator fnode = fieldNode.elements();
+	            	while(fnode.hasNext()) {
+	            		JsonNode fnchild =fnode.next();
+	            		if((fnchild.path("field-name").asText()).equals(field_name)){
+//            			System.out.println("Hurray" +fnchild.has(propName));
+	            		if(!fnchild.has(propName)){
+	            			((ObjectNode)fnchild).putArray(propName).addAll(objNode.withArray(propName));
+	            			System.out.println("Adding child array include node" + jnode.toString());
+	            		    }
+	            		    else{
+	            		    	JsonNode member = fnchild.withArray(propName);
+	            		    	((ArrayNode)member).addAll(objNode.withArray(propName));
+	            		    		}
+	            		    	
+	            		}
+	            	}
+	           	            
+	            HttpPut put = new HttpPut("http://localhost:8002"+ "/manage/v2/databases/"+dbName+"/properties?format=json");
+	    		put.addHeader("Content-type", "application/json");
+	    		put.setEntity(new StringEntity(jnode.toString()));
+	    	
+	    		HttpResponse response2 = client.execute(put);
+	    		HttpEntity respEntity = response2.getEntity();
+	    		if(respEntity != null){
+	    			String content =  EntityUtils.toString(respEntity);
+	    			System.out.println(content);
+	    		}
+	    		}
+	            else{
+	            	System.out.println("REST call for database properties returned NULL \n"+jnode.toString()+"\n"+ response1.getStatusLine().getStatusCode());
+	            }
+			}catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+			finally{
+				if(jsonstream == null){}
+				else{
+					jsonstream.close();
+				}
+				}
+			}
+
+	 public static void includeElementField(String dbName, String field_name, String namespace, String elementName) throws Exception{
+		 ObjectMapper mapper = new ObjectMapper();
+		//	ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode arrNode = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "namespace-uri", namespace);
+			childNodeObject.put( "localname", elementName);
+			childNodeObject.put("weight", 1.0);
+			arrNode.add(childNodeObject);
+			childNode.putArray("included-element").addAll(arrNode);
+		//	mainNode.put("included-elements", childNode);
+			System.out.println( childNode.toString());
+			setDatabaseFieldProperties(dbName,field_name,"included-element",childNode);
+		  
+	 }
+	 public static void includeElementFieldWithWeight(String dbName, String field_name, String namespace, String elementName, double weight) throws Exception{
+		 
+		 	ObjectMapper mapper = new ObjectMapper();
+//			ObjectNode mainNode = mapper.createObjectNode();
+			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode arrNode = mapper.createArrayNode();
+			ObjectNode childNodeObject = mapper.createObjectNode();
+			childNodeObject.put( "namespace-uri", namespace);
+			childNodeObject.put( "localname", elementName);
+			childNodeObject.put("weight", weight);
+			arrNode.add(childNodeObject);
+			childNode.putArray("included-element").addAll(arrNode);
+//			mainNode.put("included-elements", childNode);
+//			System.out.println( childNode.toString());
+			setDatabaseFieldProperties(dbName,field_name,"included-element",childNode);
+		  
+	 }
+	 public static void setupAppServicesConstraint(String dbName) throws Exception {
+		enableCollectionLexicon(dbName);
+        enableWordLexicon(dbName);
+        addRangeElementIndex(dbName, "date", "http://purl.org/dc/elements/1.1/", "date");
+        addRangeElementIndex(dbName, "int", "", "popularity");
+        addRangeElementIndex(dbName, "int", "http://test.tups.com", "rate");
+        addRangeElementIndex(dbName, "decimal", "http://test.aggr.com", "score");
+        addRangeElementIndex(dbName, "string", "", "title", "http://marklogic.com/collation/");
+        addRangeElementAttributeIndex(dbName, "decimal", "http://cloudbank.com", "price", "", "amt", "http://marklogic.com/collation/");
+        enableTrailingWildcardSearches(dbName);
+        addFieldExcludeRoot(dbName, "para");
+        includeElementFieldWithWeight(dbName, "para", "", "p", 5);
+        addRangePathIndex(dbName, "string", "/Employee/fn", "http://marklogic.com/collation/", "ignore");
+        addRangePathIndex(dbName, "int", "/root/popularity", "", "ignore");
+        addRangePathIndex(dbName, "decimal", "//@amt", "", "ignore");
+	    }
+	 public static void setupAppServicesGeoConstraint(String dbName) throws Exception {
+		 	enableCollectionLexicon(dbName);
+	        addRangeElementIndex(dbName, "dateTime", "", "bday", "http://marklogic.com/collation/");
+	        addRangeElementIndex(dbName, "int", "", "height1", "http://marklogic.com/collation/");
+	        addRangeElementIndex(dbName, "int", "", "height2", "http://marklogic.com/collation/");
+	        addRangePathIndex(dbName, "string", "/doc/name", "http://marklogic.com/collation/", "ignore");
+	        addField(dbName, "description");
+	        includeElementField(dbName, "description", "", "description");
+	        addBuiltInGeoIndex(dbName);
+	        
+	    }
+	 public static void loadBug18993(){
+		 try{
+				DefaultHttpClient client = new DefaultHttpClient();
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8011),
+						new UsernamePasswordCredentials("admin", "admin"));
+				String document ="a space b";
+				String  perm = "perm:rest-writer=read&perm:rest-writer=insert&perm:rest-writer=update&perm:rest-writer=execute";
+	            HttpPut put = new HttpPut("http://localhost:8011/v1/documents?uri=/a%20b&"+perm);
+	    		put.addHeader("Content-type", "application/xml");
+	    		put.setEntity(new StringEntity(document)); 	
+	    		HttpResponse response = client.execute(put);
+	    		HttpEntity respEntity = response.getEntity();
+	    		if(respEntity != null){
+	    			String content =  EntityUtils.toString(respEntity);
+	    			System.out.println(content);
+	    		}
+	    	 }catch (Exception e) {
+			    // writing error to Log
+			    e.printStackTrace();
+			}
+			
+	 }
+
+	 public static void setAuthentication(String level){
+		 
+	 }
+	 public static void setDefaultUser(String usr){
+		 
+	 }
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/JavaApiBatchSuite.java b/test-complete/src/test/java/com/marklogic/javaclient/JavaApiBatchSuite.java
new file mode 100644
index 000000000..e4c220240
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/JavaApiBatchSuite.java
@@ -0,0 +1,267 @@
+package com.marklogic.javaclient;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.marklogic.*;
+
+public class JavaApiBatchSuite {
+
+	/*
+	 * Copyright 2003-2013 MarkLogic Corporation. All Rights Reserved.
+	 */
+	
+	    private static final Class[] testClasses = {  TestAggregates.class,
+	    	 TestAppServicesAbsRangeConstraint.class,
+	    	 TestAppServicesCollectionConstraint.class,
+	    	 TestAppServicesConstraintCombination.class,
+	    	 TestAppServicesFieldConstraint.class,
+	    	 TestAppServicesGeoAttrPairConstraint.class,
+	    	 TestAppServicesGeoElementChildConstraint.class,
+	    	 TestAppServicesGeoElementConstraint.class,
+	    	 TestAppServicesGeoElemPairConstraint.class,
+	    	 TestAppServicesRangeConstraint.class,
+	    	 TestAppServicesRangePathIndexConstraint.class,
+	    	 TestAppServicesValueConstraint.class,
+	    	 TestAppServicesWordConstraint.class,
+	    	 TestBug18026.class,
+	    	 TestBug18724.class,
+	    	 TestBug18736.class,
+	    	 TestBug18801.class,
+	    	 TestBug18920.class,
+	    	 TestBug18990.class,
+	    	 TestBug18993.class,
+	    	 TestBug19016.class,
+	    	 TestBug19046.class,
+	    	 TestBug19092.class,
+	    	 TestBug19140.class,
+	    	 TestBug19144.class,
+	    	 TestBug19389.class,
+	    	 TestBug19443.class,
+	    	 TestBug20979.class,
+	    	 TestBug21159.class,
+	    	 TestBug21183.class,
+	    	 TestBug22037.class,
+	    	 TestBytesHandle.class,
+	    	 TestBulkReadSample1.class,
+	    	 TestBulkWriteMetadata1.class,
+	    	 TestBulkWriteSample1.class,
+	    	 TestConstraintCombination.class,
+	    	 TestCRUDModulesDb.class,
+	    	 TestDatabaseAuthentication.class,
+	    	 TestDatabaseClientConnection.class,
+	    	 TestDocumentEncoding.class,
+	    	 TestDocumentFormat.class,
+	    	 TestDocumentMimetype.class,
+	    	 TestDOMHandle.class,
+	    	 TestFieldConstraint.class,
+	    	 TestFileHandle.class,
+	    	 TestInputSourceHandle.class,
+	    	 TestInputStreamHandle.class,
+	    	 TestKeyValueSearch.class,
+	    	 TestLinkResultDocuments.class,
+	    	 TestMetadata.class,
+	    	 TestMetadataXML.class,
+	    	 TestMultithreading.class,
+	    	 TestNamespaces.class,
+	    	 TestOptimisticLocking.class,
+	    	 TestOutputStreamHandle.class,
+	    	 TestPartialUpdate.class,
+	    	 TestPatchCardinality.class,
+	    	 TestQueryByExample.class,
+	    	 TestQueryOptionBuilder.class,
+	    	 TestQueryOptionBuilderGrammar.class,
+	    	 TestQueryOptionBuilderSearchableExpression.class,
+	    	 TestQueryOptionBuilderSearchOptions.class,
+	    	 TestQueryOptionBuilderSortOrder.class,
+	    	 TestQueryOptionBuilderTransformResults.class,
+	    	 TestQueryOptionsHandle.class,
+	    	 TestQueryOptionsListHandle.class,
+	    	 TestRangeConstraint.class,
+	    	 TestRangeConstraintAbsoluteBucket.class,
+	    	 TestRangeConstraintRelativeBucket.class,
+	    	 TestRawAlert.class,
+	    	 TestRawCombinedQuery.class,
+	    	 TestRawCombinedQueryGeo.class,
+	    	 TestRawStructuredQuery.class,
+	    	 TestReaderHandle.class,
+	    	 TestRequestLogger.class,
+	    	 TestResponseTransform.class,
+	    	 TestRollbackTransaction.class,
+	    	 TestSearchMultibyte.class,
+	    	 TestSearchMultipleForests.class,
+	    	 TestSearchOnJSON.class,
+	    	 TestSearchOnProperties.class,
+	    	 TestSearchOptions.class,
+	    	 TestSearchSuggestion.class,
+	    	 TestServerAssignedDocumentURI.class,
+	    	 TestSourceHandle.class,
+	    	 TestSSLConnection.class,
+	    	 TestStandaloneGeoQuery.class,
+	    	 TestStandaloneQuery.class,
+	    	 TestStringHandle.class,
+	    	 TestStructuredQuery.class,
+	    	 TestStructuredQueryMildNot.class,
+	    	 TestStructuredSearchGeo.class,
+	    	 TestTransformXMLWithXSLT.class,
+	    	 TestValueConstraint.class,
+	    	 TestWordConstraint.class,
+	    	 TestWriteTextDoc.class,
+	    	 TestXMLDocumentRepair.class,
+	    	 TestXMLEventReaderHandle.class,
+	    	 TestXMLMultiByte.class,
+	    	 TestXMLStreamReaderHandle.class,
+	    	 ThreadClass.class,
+	    	 ThreadSearch.class,
+	    	 ThreadWrite.class };
+
+	    private JavaApiBatchSuite() {
+	        // cannot instantiate
+	    }
+
+	    public static void runTestCase(Class testCase)
+	    {
+	        Result result = JUnitCore.runClasses(testCase);
+	        for (Failure failure : result.getFailures())
+	        {
+	            System.out.println("##################################\n Test Failed "+testCase+"with reason \n "+failure.toString()+"\n############################\n");
+	        }
+	    }
+	    public static void createRESTAppServer(String restServerName ,int restPort){
+	    	try{
+	    		DefaultHttpClient client = new DefaultHttpClient();
+
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+				HttpPost post = new HttpPost("http://localhost:8002"+ "/v1/rest-apis?format=json");	
+				String JSONString = 
+						"{ \"rest-api\": {\"name\":\""+
+						restServerName +
+						"\",\"port\":\""+
+						restPort+
+						"\"}}";
+				//System.out.println(JSONString);		
+				post.addHeader("Content-type", "application/json");
+				post.setEntity(new StringEntity(JSONString));
+			
+					HttpResponse response = client.execute(post);
+					HttpEntity respEntity = response.getEntity();
+
+				    if (respEntity != null) {
+				        // EntityUtils to get the response content
+				        String content =  EntityUtils.toString(respEntity);
+				        System.out.println(content);
+				    }
+				}catch (Exception e) {
+				    // writing error to Log
+				    e.printStackTrace();
+				}
+	    }
+	    public static void createRESTUser(String usrName, String pass, String roleName ){
+	    	try{
+				DefaultHttpClient client = new DefaultHttpClient();
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+				HttpPost post = new HttpPost("http://localhost:8002"+ "/manage/v2/users?format=json");
+		 	ObjectMapper mapper = new ObjectMapper();
+			ObjectNode mainNode = mapper.createObjectNode();
+//			ObjectNode childNode = mapper.createObjectNode();
+			ArrayNode childArray = mapper.createArrayNode();
+			mainNode.put("name",usrName);
+			mainNode.put("description", "user discription");
+			mainNode.put("password", pass);
+			childArray.add(roleName);
+			mainNode.put("role", childArray);
+			//System.out.println(type + mainNode.path("range-element-indexes").path("range-element-index").toString());
+//				System.out.println(mainNode.toString());
+				post.addHeader("Content-type", "application/json");
+				post.setEntity(new StringEntity(mainNode.toString()));
+			
+				HttpResponse response = client.execute(post);
+				HttpEntity respEntity = response.getEntity();
+                  if( response.getStatusLine().getStatusCode() == 400)
+                  {
+                	  System.out.println("User already exist or a bad create request");
+                  }
+                  else if (respEntity != null) {
+				// EntityUtils to get the response content
+				String content =  EntityUtils.toString(respEntity);
+				System.out.println(content);
+				}
+                  else {System.out.print("No Proper Response");}
+				}catch (Exception e) {
+				    // writing error to Log
+				    e.printStackTrace();
+				}
+	    }
+
+	    // ----------------------------------------------------------
+	    public static void createRESTSSLAppServer(String SSLServerName ,int restPort ){
+	    	
+	    }
+	    public static void deleteRESTAppServerWithDB(String restServerName)	{
+			try{
+				DefaultHttpClient client = new DefaultHttpClient();
+
+				client.getCredentialsProvider().setCredentials(
+						new AuthScope("localhost", 8002),
+						new UsernamePasswordCredentials("admin", "admin"));
+
+				HttpDelete delete = new HttpDelete("http://localhost:8002/v1/rest-apis/"+restServerName+"?include=content&include=modules");
+				
+					HttpResponse response = client.execute(delete);
+				if(response.getStatusLine().getStatusCode()== 202){
+								Thread.sleep(3500);
+				}
+				}catch (Exception e) {
+				    // writing error to Log
+				    e.printStackTrace();
+				}
+			}	    
+	    /**
+	     * This class is for the .Net IKVM port of the junit tests.
+	     * 
+	     * @param args
+	     *            The args
+	     */
+	    public static void main(String[] args) {
+	        System.setProperty("REST.host", "localhost");
+	        System.setProperty("REST.port", "8013");
+	        System.setProperty("REST.user", "rest-admin");
+	        System.setProperty("xcc.pass", "x");
+	        createRESTUser("rest-admin","x","rest-admin");
+	        createRESTUser("rest-writer","x","rest-writer");
+	        createRESTUser("rest-reader","x","rest-reader");
+	        createRESTAppServer("JavaClientApiDefault",8013);
+	        createRESTSSLAppServer("JavaClientApiDefaultSSL",8014);
+	        for(Class testclass: testClasses ) {
+	          System.out.println("Starting the Test: "+testclass);
+	        	runTestCase(testclass);
+	        }
+	        deleteRESTAppServerWithDB("JavaClientApiDefault");
+	        deleteRESTAppServerWithDB("JavaClientApiDefaultSSL");
+	        
+	    }
+
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/Product.java b/test-complete/src/test/java/com/marklogic/javaclient/Product.java
new file mode 100644
index 000000000..a46118151
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/Product.java
@@ -0,0 +1,46 @@
+package com.marklogic.javaclient;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Product 
+{
+	String name;
+	String industry;
+	String description;
+		
+	public Product() 
+	{
+		super();
+	}
+	
+	public String getName() 
+	{
+		return name;
+	}
+		
+	public void setName(String name) 
+	{
+		this.name = name;
+	}
+		
+	public String getIndustry() 
+	{
+		return industry;
+	}
+		
+	public void setIndustry(String industry) 
+	{
+		this.industry = industry;
+	}
+		
+	public String getDescription() 
+	{
+		return description;
+	}
+		
+	public void setDescription(String description) 
+	{
+		this.description = description;
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAggregates.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAggregates.java
new file mode 100644
index 000000000..4fc9f7b50
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAggregates.java
@@ -0,0 +1,378 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.TuplesHandle;
+import com.marklogic.client.io.ValuesHandle;
+import com.marklogic.client.query.AggregateResult;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.ValuesDefinition;
+
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+
+
+public class TestAggregates extends BasicJavaClientREST  {
+
+	
+	private static String dbName = "TestAggregatesDB";
+	private static String [] fNames = {"TestAggregatesDB-1"};
+	private static String restServerName = "REST-Java-Client-API-TestAggregateServer";
+	private static int restPort = 8011;
+ 
+    @BeforeClass
+	public static void setUp() throws Exception 
+	{
+	   System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+	  setupAppServicesConstraint(dbName);
+	  
+	 // System.out.println(" and "+ serverName + dbName + restServerName);
+	}
+	
+    @After
+    public  void testCleanUp() throws Exception
+    {
+    	clearDB(restPort);
+    	System.out.println("Running clear script");
+    }
+	@Test
+	public void testValuesAggregates() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValuesAggregates");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/values-aggr/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity", "aggregatesOpt.xml");
+		queryDef.setAggregate("sum", "avg", "max", "min");
+		queryDef.setName("pop-aggr");
+		
+		// create handle
+		ValuesHandle valuesHandle = new ValuesHandle();
+		queryMgr.values(queryDef, valuesHandle);
+						
+        AggregateResult[] agg = valuesHandle.getAggregates();
+        System.out.println(agg.length);
+        assertEquals("Invalid length", 4, agg.length);
+        int sum = agg[0].get("xs:int", Integer.class);
+        double avg = agg[1].get("xs:double", Double.class);
+        int max = agg[2].get("xs:int", Integer.class);
+        int min = agg[3].get("xs:int", Integer.class);
+        System.out.println(sum);
+        assertEquals("Invalid sum", 22, sum);
+        System.out.println(avg);
+        assertEquals("Invalid avg", 4.4, avg,0);
+        System.out.println(max);
+        assertEquals("Invalid max", 5, max);
+        System.out.println(min);
+        assertEquals("Invalid min", 3, min);
+        System.out.println(agg[0].getValue());
+        assertEquals("Invalid sum", "22", agg[0].getValue());
+        System.out.println(agg[1].getValue());
+        assertEquals("Invalid avg", "4.4", agg[1].getValue());
+        System.out.println(agg[2].getValue());
+        assertEquals("Invalid max", "5", agg[2].getValue());
+        System.out.println(agg[3].getValue());
+        assertEquals("Invalid min", "3", agg[3].getValue());
+        		
+        
+        QueryManager queryMgr1 = client.newQueryManager();
+		// create query def
+		ValuesDefinition queryDef1 = queryMgr1.newValuesDefinition("score", "aggregatesOpt.xml");
+		queryDef1.setAggregate("sum", "avg", "max", "min");
+		queryDef1.setName("score-aggr");
+        
+		// create handle
+		ValuesHandle valuesHandle1 = new ValuesHandle();
+		queryMgr.values(queryDef1, valuesHandle1);
+		
+		AggregateResult[] agg1 = valuesHandle1.getAggregates();
+		
+        System.out.println("Length :"+agg1.length+" Value :"+ agg[1].getValue());
+        double score_sum =agg1[0].get("xs:double", Double.class);
+        double score_avg = agg1[1].get("xs:double", Double.class);
+        double score_max = agg1[2].get("xs:double", Double.class);
+        double score_min = agg1[3].get("xs:double", Double.class);
+		System.out.println("Sum :"+score_sum+" Average :"+score_avg+" Max Score :"+score_max+" Min Score :"+score_min);
+       
+		// release client
+		client.release();		
+	}
+	
+	
+	@Test
+	public void testValuesAggregatesWithNS() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValuesAggregatesWithNS");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/values-aggr-ns/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("score", "aggregatesOpt.xml");
+		queryDef.setAggregate("sum", "avg", "max", "min");
+		queryDef.setName("score-aggr");
+		
+		// create handle
+		ValuesHandle valuesHandle = new ValuesHandle();
+		queryMgr.values(queryDef, valuesHandle);
+						
+        AggregateResult[] agg = valuesHandle.getAggregates();
+        System.out.println(agg.length);
+        assertEquals("Invalid length", 4, agg.length);
+        double sum = agg[0].get("xs:double", Double.class);
+        double avg = agg[1].get("xs:double", Double.class);
+        double max = agg[2].get("xs:double", Double.class);
+        double min = agg[3].get("xs:double", Double.class);
+        
+        DecimalFormat df = new DecimalFormat("###.##");
+        String roundedSum = df.format(sum);
+        String roundedAvg = df.format(avg);
+        
+        System.out.println("roundedSum :"+roundedSum);
+        assertEquals("Invalid sum", "272.73", roundedSum);
+        System.out.println("roundedAvg :"+roundedAvg);
+        assertEquals("Invalid avg", "54.55", roundedAvg);
+        System.out.println("Max :"+max);
+        assertEquals("Invalid max", 92.45, max,0);
+        System.out.println("Min :"+min);
+        assertEquals("Invalid min", 12.34, min,0);
+        System.out.println("agg[0] :"+agg[0].getValue()+" After Formatting :"+df.format(agg[0].get("xs:double", Double.class)));
+        assertEquals("Invalid sum", "272.73", df.format(agg[0].get("xs:double", Double.class)));
+        System.out.println("agg[1] :"+agg[1].getValue()+" After Formatting :"+df.format(agg[1].get("xs:double", Double.class)));
+        assertEquals("Invalid avg", "54.55",df.format(agg[1].get("xs:double", Double.class)));
+        System.out.println("agg[2] :"+agg[2].getValue());
+        assertEquals("Invalid max", "92.45", df.format(agg[2].get("xs:double", Double.class)));
+        System.out.println("agg[3] :"+agg[3].getValue());
+        assertEquals("Invalid min", "12.34", df.format(agg[3].get("xs:double", Double.class)));
+        		
+		// release client
+		client.release();		
+	}
+	@Test
+	public void testTuplesAggregates() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testTuplesAggregates");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/tuples-aggr/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity", "aggregatesOpt.xml");
+		queryDef.setAggregate("correlation", "covariance");
+		queryDef.setName("pop-rate-tups");
+		
+		// create handle
+		TuplesHandle tuplesHandle = new TuplesHandle();
+		queryMgr.tuples(queryDef, tuplesHandle);
+						
+        AggregateResult[] agg = tuplesHandle.getAggregates();
+        System.out.println(agg.length);
+        assertEquals("Invalid length", 2, agg.length);
+        double correlation = agg[0].get("xs:double", Double.class);
+        double covariance = agg[1].get("xs:double", Double.class);
+        
+        DecimalFormat df = new DecimalFormat("###.##");
+        String roundedCorrelation = df.format(correlation);
+        String roundedCovariance = df.format(covariance);
+        
+        System.out.println(roundedCorrelation);
+        System.out.println(roundedCovariance);
+        
+        assertEquals("Invalid correlation", "0.26", roundedCorrelation);
+        assertEquals("Invalid covariance", "0.35", roundedCovariance);
+        		
+		// release client
+		client.release();		
+	}
+	@Test
+	public void testValuesAggregatesWithJson() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValuesAggregatesWithJson");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/values-aggr/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity", "aggregatesOpt.xml");
+		queryDef.setAggregate("sum", "avg", "max", "min");
+		queryDef.setName("pop-aggr");
+		
+		// create handle
+		StringHandle resultHandle = new StringHandle().withFormat(Format.JSON);
+		queryMgr.values(queryDef, resultHandle);
+						
+		String result = resultHandle.get();
+		
+		System.out.println(result);
+		
+		assertEquals("{", result.substring(0, 1));        		
+		// release client
+		client.release();		
+	}
+	@Test
+	public void testValuesAggregatesThreeOccurences() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValuesAggregatesThreeOccurences");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml"};
+		String queryOptionName = "aggregatesOpt3Occ.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/values-aggr/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("date", "aggregatesOpt3Occ.xml");
+		queryDef.setAggregate("count");
+		queryDef.setName("date-val");
+		
+		// create handle
+		ValuesHandle valuesHandle = new ValuesHandle();
+		queryMgr.values(queryDef, valuesHandle);
+						
+        AggregateResult[] agg = valuesHandle.getAggregates();
+        assertEquals("Wrong counting","4",agg[0].getValue());
+        
+        ValuesDefinition queryDef1 = queryMgr.newValuesDefinition("popularity", "aggregatesOpt3Occ.xml");
+		queryDef1.setAggregate("correlation", "covariance");
+		queryDef1.setName("pop-rate-tups");
+		
+		// create handle
+		TuplesHandle tuplesHandle = new TuplesHandle();
+		queryMgr.tuples(queryDef1, tuplesHandle);
+						
+        AggregateResult[] aggn = tuplesHandle.getAggregates();
+        System.out.println(aggn.length);
+        assertEquals("Invalid length", 2, aggn.length);
+        double correlation = aggn[0].get("xs:double", Double.class);
+        double covariance = aggn[1].get("xs:double", Double.class);
+        
+        DecimalFormat df = new DecimalFormat("###.##");
+        String roundedCorrelation = df.format(correlation);
+        String roundedCovariance = df.format(covariance);
+        
+        System.out.println(roundedCorrelation);
+        System.out.println(roundedCovariance);
+        assertEquals("Invalid correlation", "0.43", roundedCorrelation);
+        assertEquals("Invalid covariance", "0.67", roundedCovariance);
+		// release client
+		client.release();		
+	}
+	@Test
+	public void testValuesAggregatesFiveOccurences() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValuesAggregatesThreeOccurences");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml"};
+		String queryOptionName = "aggregatesOpt5Occ.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/values-aggr/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("title", "aggregatesOpt5Occ.xml");
+		queryDef.setAggregate("count");
+		queryDef.setName("title-val");
+		
+		// create handle
+		ValuesHandle valuesHandle = new ValuesHandle();
+		queryMgr.values(queryDef, valuesHandle);
+						
+        AggregateResult[] agg = valuesHandle.getAggregates();
+        System.out.println(agg.length);
+        System.out.println(agg[0].getValue());
+
+		// release client
+		client.release();		
+	}
+	
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down" );
+	
+	tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesAbsRangeConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesAbsRangeConstraint.java
new file mode 100644
index 000000000..c061f8cd7
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesAbsRangeConstraint.java
@@ -0,0 +1,90 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+
+import org.junit.*;
+
+
+
+public class TestAppServicesAbsRangeConstraint extends BasicJavaClientREST  {
+
+	
+	private static String dbName = "AbsRangeConstraintDB";
+	private static String [] fNames = {"AbsRangeConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+	@Test
+	public void testWithVariousGrammarAndWordQuery() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithVariousGrammarAndWordQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "absRangeConstraintWithVariousGrammarAndWordQueryOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/abs-range-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("(pop:high OR pop:medium) AND price:medium AND intitle:served");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar served", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("12.34", "string(//*[local-name()='result'][1]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][1]//*[local-name()='popularity'])", resultDoc);
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='facet-value']//@*[local-name()='count'])", resultDoc);
+		assertXpathEvaluatesTo("High", "string(//*[local-name()='facet-value'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:or-query((cts:element-range-query(fn:QName(\"\", \"popularity\"), \">=\", xs:int(\"5\"), (), 1), cts:and-query((cts:element-range-query(fn:QName(\"\", \"popularity\"), \">=\", xs:int(\"3\"), (), 1), cts:element-range-query(fn:QName(\"\", \"popularity\"), \"<\", xs:int(\"5\"), (), 1)), ()))), cts:element-attribute-range-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \">=\", 3.0, (), 1), cts:element-attribute-range-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \"<\", 14.0, (), 1), cts:element-word-query(fn:QName(\"\", \"title\"), \"served\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesCollectionConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesCollectionConstraint.java
new file mode 100644
index 000000000..c66adb98c
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesCollectionConstraint.java
@@ -0,0 +1,247 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathNotExists;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesCollectionConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesCollectionConstraintDB";
+	private static String [] fNames = {"AppServicesCollectionConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+
+	//@Test
+	public void testWithFacet() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testWithFacet");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "collectionConstraintWithFacetOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("coll:set3");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("For 1945", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='facet-value']//@*[local-name()='count'])", resultDoc);
+		assertXpathEvaluatesTo("set3", "string(//*[local-name()='facet-value'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:collection-query(\"http://test.com/set3\"), (\"score-logtfidf\",\"faceted\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	
+	@Test
+	public void testWithNoFacet() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testWithNoFacet");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "collectionConstraintWithNoFacetOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("coll:set3");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+	
+			System.out.println(convertXMLDocumentToString(resultDoc));	
+//		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+//		assertXpathEvaluatesTo("For 1945", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathNotExists("//search:facet-value[@count='1']", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:collection-query(\"http://test.com/set3\"), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	
+//	@Test
+	public void testWithWordConstraintAndGoogleGrammar() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithWordConstraintAndGoogleGrammar");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "collectionConstraintWithWordConstraintAndGoogleGrammarOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:collection-query(\"http://test.com/set1\"), cts:collection-query(\"http://test.com/set5\"), cts:not-query(cts:element-word-query(fn:QName(\"\", \"title\"), \"memex\", (\"lang=en\"), 1), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesConstraintCombination.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesConstraintCombination.java
new file mode 100644
index 000000000..93a71471c
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesConstraintCombination.java
@@ -0,0 +1,155 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestAppServicesConstraintCombination extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesConstraintCombinationDB";
+	private static String [] fNames = {"AppServicesConstraintCombinationDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+
+@Test
+	public void testWithValueAndRange() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithValueAndRange");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "appservicesConstraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/appservices-combination-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("id:00*2 AND date:2006-02-02");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-range-query(fn:QName(\"http://purl.org/dc/elements/1.1/\", \"date\"), \"=\", xs:date(\"2006-02-02\"), (), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test	
+	public void testWithAll() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithAll");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "appservicesConstraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex AND (pop:high OR pop:medium) AND price:low AND id:**11 AND date:2005-01-01 AND (para:Bush AND -para:memex)");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:collection-query(\"http://test.com/set1\"), cts:collection-query(\"http://test.com/set5\"), cts:not-query(cts:element-word-query(fn:QName(\"\", \"title\"), \"memex\", (\"lang=en\"), 1), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesFieldConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesFieldConstraint.java
new file mode 100644
index 000000000..0a84314bb
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesFieldConstraint.java
@@ -0,0 +1,90 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestAppServicesFieldConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesFieldConstraintDB";
+	private static String [] fNames = {"AppServicesFieldConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+
+
+@Test
+	public void testWithSnippetAndVariousGrammarAndWordQuery() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithSnippetAndVariousGrammarAndWordQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "fieldConstraintWithSnippetAndVariousGrammarAndWordQueryOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/field-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("(para:Bush AND -para:memex) OR id:0026 AND memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='match'][2]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][3]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Bush", "string(//*[local-name()='result'][2]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+			    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:or-query((cts:element-range-query(fn:QName(\"\", \"popularity\"), \">=\", xs:int(\"5\"), (), 1), cts:and-query((cts:element-range-query(fn:QName(\"\", \"popularity\"), \">=\", xs:int(\"3\"), (), 1), cts:element-range-query(fn:QName(\"\", \"popularity\"), \"<\", xs:int(\"5\"), (), 1)), ()))), cts:element-attribute-range-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \">=\", 3.0, (), 1), cts:element-attribute-range-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \"<\", 14.0, (), 1), cts:element-word-query(fn:QName(\"\", \"title\"), \"served\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoAttrPairConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoAttrPairConstraint.java
new file mode 100644
index 000000000..a456afe71
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoAttrPairConstraint.java
@@ -0,0 +1,270 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesGeoAttrPairConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesGeoAttrPairConstraintDB";
+	private static String [] fNames = {"AppServicesGeoAttrPairConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+@Test	
+	public void testPointPositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointPositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-attr-pair:\"12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testPointPositiveLatNegativeLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointNegativeLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-attr-pair:\"12,-5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,-5 12,-5 12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testNegativePointInvalidValue() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativePointInvalidValue");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-attr-pair:\"12,A\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		
+		String result = "";
+		
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+			Document resultDoc = resultsHandle.get();
+			result = convertXMLDocumentToString(resultDoc).toString();
+			System.out.println("Result : "+result);
+			
+		} catch (Exception e) { e.toString(); }
+		
+		assertTrue("Expected Warning message is not thrown", result.contains("[Invalid text, cannot parse geospatial point from '12,A'.]"));
+						
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testCirclePositiveLatNegativeLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testCirclePositiveLatNegativeLang");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"@70 12,-5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,-5 12,-5 12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,-5 11,-5 11 -5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,-4 12,-4 12 -4", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("bill_kara 13,-5 13,-5 13 -5", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_gale 12,-6 12,-6 12 -6", "string(//*[local-name()='result'][5]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@Test
+	public void testBoxPositiveLatNegativeLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testBoxPositiveLatNegativeLang");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"[11,-5,12,-4]\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,-5 12,-5 12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,-5 11,-5 11 -5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,-4 12,-4 12 -4", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testCircleAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testCircleAndWord");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"@70 12,-5\" AND karl_kara");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint15.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElemPairConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElemPairConstraint.java
new file mode 100644
index 000000000..7d520ea88
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElemPairConstraint.java
@@ -0,0 +1,272 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesGeoElemPairConstraint extends BasicJavaClientREST {
+
+//	private static String serverName = "";
+	private static String dbName = "AppServicesGeoElemPairConstraintDB";
+	private static String [] fNames = {"AppServicesGeoElemPairConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+	@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+	@After
+	public  void testCleanUp() throws Exception
+	{
+		clearDB(8011);
+		System.out.println("Running clear script");
+	}
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testPointPositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointPositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testPointNegativeLatPositiveLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointNegativeLatPositiveLang");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"-12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,5 -12,5 -12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testNegativePointInvalidValue() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativePointInvalidValue");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"-12,A\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		String result = "";
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+			Document resultDoc = resultsHandle.get();
+			result = convertXMLDocumentToString(resultDoc).toString();
+			System.out.println("Result : "+result);
+		} catch (Exception e) { e.toString(); }
+		
+		assertTrue("Expected Warning message is not thrown", result.contains("[Invalid text, cannot parse geospatial point from '-12,A'.]"));
+		
+				
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testCircleNegativeLatPositiveLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testCircleNegativeLatPositiveLang");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"@70 -12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("bill_kara -13,5 -13,5 -13 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_gale -12,6 -12,6 -12 6", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,5 -12,5 -12 5", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara -11,5 -11,5 -11 5", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill -12,4 -12,4 -12 4", "string(//*[local-name()='result'][5]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBoxNegativeLatPositiveLang() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testBoxNegativeLatPositiveLang");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"[-12,4,-11,5]\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,5 -12,5 -12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara -11,5 -11,5 -11 5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill -12,4 -12,4 -12 4", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBoxAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBoxAndWord");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-pair:\"[-12,4,-11,5]\" AND karl_kara");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint20.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementChildConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementChildConstraint.java
new file mode 100644
index 000000000..daa15e05b
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementChildConstraint.java
@@ -0,0 +1,275 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesGeoElementChildConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesGeoElementChildConstraintDB";
+	private static String [] fNames = {"AppServicesGeoElementChildConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+@SuppressWarnings("deprecation")
+@Test
+	public void testPointPositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointPositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testPointNegativeLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointNegativeLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"-12,-5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,-5 -12,-5 -12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testNegativePointInvalidValue() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativePointInvalidValue");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"12,A\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		
+		String result = "";
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+			Document resultDoc = resultsHandle.get();
+			result = convertXMLDocumentToString(resultDoc).toString();
+			System.out.println("Result : "+result);
+			
+		} catch (Exception e) { e.toString(); }
+		
+		assertTrue("Expected Warning message is not thrown", result.contains("[Invalid text, cannot parse geospatial point from '12,A'.]"));
+		
+				
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testCircleNegativeLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testCircleNegativeLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"@70 -12,-5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara -11,-5 -11,-5 -11 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill -12,-4 -12,-4 -12 -4", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,-5 -12,-5 -12 -5", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("bill_kara -13,-5 -13,-5 -13 -5", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_gale -12,-6 -12,-6 -12 -6", "string(//*[local-name()='result'][5]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBoxNegativeLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testBoxNegativeLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"[-12,-5,-11,-4]\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara -11,-5 -11,-5 -11 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill -12,-4 -12,-4 -12 -4", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,-5 -12,-5 -12 -5", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_jill -11,-4 -11,-4 -11 -4", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBoxAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointAndWord");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem-child:\"[-12,-5,-11,-4]\" AND karl_kara");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint2.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementConstraint.java
new file mode 100644
index 000000000..d723d2279
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesGeoElementConstraint.java
@@ -0,0 +1,290 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesGeoElementConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesGeoConstraintDB";
+	private static String [] fNames = {"AppServicesGeoConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+
+@Test
+	public void testPointPositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointPositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testPointNegativeLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointNegativeLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"-12,-5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara -12,-5 -12,-5 -12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@Test
+	public void testNegativePointInvalidValue() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativePointInvalidValue");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"12,A\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		
+		String result = "";
+		
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+			Document resultDoc = resultsHandle.get();
+			result = convertXMLDocumentToString(resultDoc).toString();
+			System.out.println("Result : "+result);
+		} catch (Exception e) { e.toString(); }
+		
+		assertTrue("Expected Warning message is not thrown", result.contains("[Invalid text, cannot parse geospatial point from '12,A'.]"));
+		
+				
+		// release client
+		client.release();		
+	}
+
+
+@Test	
+	public void testCirclePositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testCirclePositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"@70 12,5\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("bill_kara 13,5 13,5 13 5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_gale 12,6 12,6 12 6", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,5 11,5 11 5", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,4 12,4 12 4", "string(//*[local-name()='result'][5]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testBoxPositiveLangLat() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testBoxPositiveLangLat");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"[11,4,12,5]\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_jill 11,4 11,4 11 4", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,5 11,5 11 5", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,4 12,4 12 4", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@Test
+	public void testPointAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPointAndWord");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 9; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("geo-elem:\"150,-140\" AND john");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint8.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangeConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangeConstraint.java
new file mode 100644
index 000000000..0d1ac60fd
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangeConstraint.java
@@ -0,0 +1,189 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesRangeConstraint extends BasicJavaClientREST {
+
+//	private String serverName = "";
+	private static String dbName = "AppServicesRangeConstraintDB";
+	private static String [] fNames = {"AppServicesRangeConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+//	  super.setUp();
+//	  serverName = getConnectedServerName();
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+@SuppressWarnings("deprecation")
+@Test
+	public void testWithWordSearch() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithWordSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "rangeConstraintWithWordSearchOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/range-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("date:2006-02-02 OR policymaker");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("2008-04-04", "string(//*[local-name()='result'][1]//*[local-name()='date'])", resultDoc);
+		assertXpathEvaluatesTo("2006-02-02", "string(//*[local-name()='result'][2]//*[local-name()='date'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar served as a prominent policymaker and public intellectual.", "string(//*[local-name()='result'][1]//*[local-name()='p'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article described a device called a Memex.", "string(//*[local-name()='result'][2]//*[local-name()='p'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-range-query(fn:QName(\"http://purl.org/dc/elements/1.1/\",\"date\"), \"=\", xs:date(\"2006-02-02\"), (), 1), cts:word-query(\"policymaker\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	/*public void testNegativeWithoutIndexSettings() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativeWithoutIndexSettings");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "rangeConstraintNegativeWithoutIndexSettingsOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/range-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("title:Bush");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		
+		String exception = "";
+		
+		// run search
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+		} 
+		catch (Exception e) { exception = e.toString(); }
+		
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: search failed: Internal Server ErrorServer Message: XDMP-ELEMRIDXNOTFOUND";
+		
+		//assertEquals("Wrong exception", expectedException, exception);
+	    boolean exceptionIsThrown = exception.contains(expectedException);
+	    assertTrue("Exception is not thrown", exceptionIsThrown);
+		
+		// release client
+		client.release();		
+	}*/
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testNegativeTypeMismatch() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNegativeTypeMismatch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "rangeConstraintNegativeTypeMismatchOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/range-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("date:2006-02-02");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		
+		String exception = "";
+		
+		// run search
+		try
+		{
+			queryMgr.search(querydef, resultsHandle);
+		} 
+		catch (Exception e) { exception = e.toString(); }
+		
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: search failed: Bad Request. Server Message: XDMP-ELEMRIDXNOTFOUND";
+		
+		//assertEquals("Wrong exception", expectedException, exception);
+		boolean exceptionIsThrown = exception.contains(expectedException);
+	    assertTrue("Exception is not thrown", exceptionIsThrown);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+//		super.tearDown();
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangePathIndexConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangePathIndexConstraint.java
new file mode 100644
index 000000000..f0b66914d
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesRangePathIndexConstraint.java
@@ -0,0 +1,256 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptions;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestAppServicesRangePathIndexConstraint extends BasicJavaClientREST {
+
+	private static String dbName = "AppServicesPathIndexConstraintDB";
+	private static String [] fNames = {"AppServicesPathIndexConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+@SuppressWarnings("deprecation")
+@Test
+	public void testPathIndex() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPathIndex");
+		
+		String[] filenames = {"pathindex1.xml", "pathindex2.xml"};
+		String queryOptionName = "pathIndexConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pindex:Aries");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-constraint/pathindex1.xml", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-constraint/pathindex2.xml", "string(//*[local-name()='result'][2]//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();
+		
+		// ***********************************************
+		// *** Running test path index with constraint ***
+		// ***********************************************
+		
+        System.out.println("Running testPathIndexWithConstraint");
+
+		client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-constraint/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+				
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+				
+		// create query options handle
+		QueryOptionsHandle handle = new QueryOptionsHandle();
+		
+		handle.withConstraints(builder.constraint("lastname", builder.word(builder.elementTermIndex(new QName("ln")))), builder.constraint("pindex", builder.range(builder.pathIndex("/Employee/fn", null, builder.stringRangeType(QueryOptions.DEFAULT_COLLATION)))));
+		
+		// write query options
+        optionsMgr.writeOptions("PathIndexWithConstraint", handle);
+		
+        // create query manager
+     	queryMgr = client.newQueryManager();
+     	
+     	// create query def
+     	querydef = queryMgr.newStringDefinition("PathIndexWithConstraint");
+        querydef.setCriteria("pindex:Aries AND lastname:Yuwono");
+        
+     	StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("PathIndexWithConstraint");
+     	StructuredQueryDefinition queryPathIndex = qb.rangeConstraint("pindex", Operator.EQ, "Aries");
+     	StructuredQueryDefinition queryWord = qb.wordConstraint("lastname", "Yuwono");
+     	StructuredQueryDefinition queryFinal = qb.and(queryPathIndex, queryWord);
+     	
+     	// create handle
+     	resultsHandle = new DOMHandle();
+     	queryMgr.search(queryFinal, resultsHandle);
+     	
+     	resultDoc = resultsHandle.get();
+     	
+     	assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-constraint/pathindex1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+				
+		// release client
+		client.release();
+
+		// ***********************************************
+		// *** Running test path index on int ***
+		// ***********************************************
+		
+        System.out.println("Running testPathIndexOnInt");
+        
+        String[] filenames2 = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames2)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-constraint/", "XML");
+		}
+		
+		// create query options manager
+		optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+				
+		// create query options builder
+		builder = new QueryOptionsBuilder();
+				
+		// create query options handle
+		handle = new QueryOptionsHandle();
+		
+		handle.withTransformResults(builder.rawResults());
+		handle.withConfiguration(builder.configure().debug(true).returnMetrics(false).returnQtext(false));
+		handle.withConstraints(builder.constraint("amount", builder.range(builder.pathIndex("//@amt", null, builder.rangeType("xs:decimal")))), builder.constraint("pop", builder.range(builder.pathIndex("/root/popularity", null, builder.rangeType("xs:int")))));
+		
+		// write query options
+        optionsMgr.writeOptions("PathIndexWithConstraint", handle);
+		
+        // create query manager
+     	queryMgr = client.newQueryManager();
+   
+        // create query builder
+     	qb = queryMgr.newStructuredQueryBuilder("PathIndexWithConstraint");
+     	StructuredQueryDefinition queryPathIndex1 = qb.rangeConstraint("pop", Operator.EQ, "5");
+     	StructuredQueryDefinition queryPathIndex2 = qb.rangeConstraint("amount", Operator.EQ, "0.1");
+     	queryFinal = qb.and(queryPathIndex1, queryPathIndex2);
+     	
+     	// create handle
+     	resultsHandle = new DOMHandle();
+     	queryMgr.search(queryFinal, resultsHandle);
+     	
+     	resultDoc = resultsHandle.get();
+     	
+     	assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-constraint/constraint1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+				
+		// release client
+		client.release();		
+	}
+	
+		
+	/*
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testPathIndexWithConstraint() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testPathIndexWithConstraint");
+		
+		String[] filenames = {"pathindex1.xml", "pathindex2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-constraint/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+				
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+				
+		// create query options handle
+		QueryOptionsHandle handle = new QueryOptionsHandle();
+		
+		handle.withConstraints(builder.constraint("lastname", builder.word(builder.elementTermIndex(new QName("ln")))), builder.constraint("pindex", builder.range(builder.pathIndex("/Employee/fn", null, builder.stringRangeType(QueryOptions.DEFAULT_COLLATION)))));
+		
+		// write query options
+        optionsMgr.writeOptions("PathIndexWithConstraint", handle);
+        System.out.println(optionsMgr.readOptions("PathIndexWithConstraint", new StringHandle()).get());
+		
+        // create query manager
+     	QueryManager queryMgr = client.newQueryManager();
+     	
+     	// create query def
+     	StringQueryDefinition querydef = queryMgr.newStringDefinition("PathIndexWithConstraint");
+        querydef.setCriteria("pindex:Aries AND lastname:Yuwono");
+        
+     	StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("PathIndexWithConstraint");
+     	StructuredQueryDefinition queryPathIndex = qb.rangeConstraint("pindex", Operator.EQ, "Aries");
+     	StructuredQueryDefinition queryWord = qb.wordConstraint("lastname", "Yuwono");
+     	StructuredQueryDefinition queryFinal = qb.and(queryPathIndex, queryWord);
+     	
+     	// create handle
+     	DOMHandle resultsHandle = new DOMHandle();
+     	queryMgr.search(queryFinal, resultsHandle);
+     	
+     	Document resultDoc = resultsHandle.get();
+     	
+     	System.out.println(convertXMLDocumentToString(resultDoc));
+				
+		// release client
+		client.release();		
+	}
+    */
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesValueConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesValueConstraint.java
new file mode 100644
index 000000000..f0b21cd1e
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesValueConstraint.java
@@ -0,0 +1,268 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+
+public class TestAppServicesValueConstraint extends BasicJavaClientREST {
+
+	private static String dbName = "AppServicesValueConstraintDB";
+	private static String [] fNames = {"AppServicesValueConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+	@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	@After
+	public  void testCleanUp() throws Exception
+	{
+		clearDB(8011);
+		System.out.println("Running clear script");
+	}
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testWildcard() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWildcard");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("id:00*2 OR id:0??6");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testGoogleStyleGrammar() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testGoogleStyleGrammar");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintGoogleGrammarOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("title:\"The memex\" OR (id:0113 AND date:2007-03-03)");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("For 1945", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The memex", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("0113", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-value-query(fn:QName(\"\", \"title\"), \"The memex\", (\"lang=en\"), 1), cts:and-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"0113\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"http://purl.org/dc/elements/1.1/\", \"date\"), \"2007-03-03\", (\"lang=en\"), 1)), ()))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testWithoutIndexSettingsAndNS() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithoutIndexSettingsAndNS");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("id:0012");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:element-value-query(fn:QName(\"\", \"id\"), \"0012\", (\"lang=en\"), 1), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testWithIndexSettingsAndNS() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithIndexSettingsAndNS");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("dt:2007-03-03");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("2007-03-03", "string(//*[local-name()='result'][1]//*[local-name()='date'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:element-value-query(fn:QName(\"http://purl.org/dc/elements/1.1/\", \"date\"), \"2007-03-03\", (\"lang=en\"), 1), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testSpaceSeparated() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testSpaceSeparated");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintSpaceSeparatedOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("title:\"Vannevar Bush\" price:0.1");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result']//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("0.1", "string(//*[local-name()='result']//@*[local-name()='amt'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query((cts:element-value-query(fn:QName(\"\", \"title\"), \"Vannevar Bush\", (\"lang=en\"), 1), cts:element-attribute-value-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \"0.1\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesWordConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesWordConstraint.java
new file mode 100644
index 000000000..1a6be2255
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestAppServicesWordConstraint.java
@@ -0,0 +1,186 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.marklogic.client.query.QueryManager;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestAppServicesWordConstraint extends BasicJavaClientREST {
+
+	private static String dbName = "AppServicesWordConstraintDB";
+	private static String [] fNames = {"AppServicesWordConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}
+@SuppressWarnings("deprecation")
+@Test
+	public void testWithElementAndAttributeIndex() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithElementAndAttributeIndex");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "wordConstraintWithElementAndAttributeIndexOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/word-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:1945 OR inprice:12");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("For 1945", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar served", "string(//*[local-name()='result'][3]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("1.23", "string(//*[local-name()='result'][1]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("0.12", "string(//*[local-name()='result'][2]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("12.34", "string(//*[local-name()='result'][3]//@*[local-name()='amt'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-range-query(fn:QName(\"http://purl.org/dc/elements/1.1/\", \"date\"), \"=\", xs:date(\"2006-02-02\"), (), 1), cts:word-query(\"policymaker\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testWithNormalWordQuery() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithNormalWordQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "wordConstraintWithNormalWordQueryOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/word-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("Memex  OR inprice:.12");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The memex", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("0.12", "string(//*[local-name()='result'][1]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("123.45", "string(//*[local-name()='result'][2]//@*[local-name()='amt'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:word-query(\"Memex\", (\"lang=en\"), 1), cts:element-attribute-word-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \".12\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testWithTermOptionCaseInsensitive() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithTermOptionCaseInsensitive");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "wordConstraintWithTermOptionCaseInsensitiveOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/word-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:for  OR price:0.12");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("For 1945", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("1.23", "string(//*[local-name()='result'][1]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("0.12", "string(//*[local-name()='result'][2]//@*[local-name()='amt'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-word-query(fn:QName(\"\", \"title\"), \"for\", (\"case-insensitive\",\"lang=en\"), 1), cts:element-attribute-range-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \"=\", 0.12, (), 1))), (\"score-logtfidf\",\"faceted\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18026.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18026.java
new file mode 100644
index 000000000..938f0f82d
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18026.java
@@ -0,0 +1,175 @@
+package com.marklogic.javaclient;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.XpathEngine;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.InputStreamHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestBug18026 extends BasicJavaClientREST {
+	
+	private static String dbName = "Bug18026DB";
+	private static String [] fNames = {"Bug18026DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	private XpathEngine xpather;
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBug18026() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original.xml";
+		String uri = "/write-buffer/";
+		byte[] before = null;
+		byte[] after = null;
+		String strBefore = null;
+		String strAfter = null;
+		
+		System.out.println("Running testBug18026");
+		
+        XMLUnit.setIgnoreAttributeOrder(true);
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setNormalize(true);
+        XMLUnit.setNormalizeWhitespace(true);
+        XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
+
+        HashMap namespaces = new HashMap();
+        namespaces.put("rapi", "http://marklogic.com/rest-api");
+        namespaces.put("prop", "http://marklogic.com/xdmp/property");
+        namespaces.put("xs",   "http://www.w3.org/2001/XMLSchema");
+        namespaces.put("xsi",  "http://www.w3.org/2001/XMLSchema-instance");
+
+        SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext(namespaces);
+
+        xpather = XMLUnit.newXpathEngine();
+        xpather.setNamespaceContext(namespaceContext);
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		Document readDoc = expectedXMLDocument(filename);
+		
+		DOMHandle dHandle = new DOMHandle();
+		dHandle.set(readDoc);
+		before = dHandle.toBuffer();
+		strBefore = new String(before);
+		System.out.println("Before: " + strBefore);
+		
+		// write doc
+		XMLDocumentManager docMgr = client.newXMLDocumentManager(); 
+		String docId = uri + filename;
+		docMgr.write(docId, dHandle);
+		
+		// read doc
+		docMgr.read(docId, dHandle);
+		dHandle.get();
+		
+		after = dHandle.toBuffer();
+		strAfter = new String(after);
+		System.out.println("After: " + strAfter);
+		
+		assertXMLEqual("Buffer is not the same", strBefore, strAfter);
+		
+	    // release client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBug18026WithJson() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "json-original.json";
+		String uri = "/write-buffer/";
+		byte[] before = null;
+		byte[] after = null;
+		String strBefore = null;
+		String strAfter = null;
+		
+		System.out.println("Running testBug18026WithJson");
+		
+        XMLUnit.setIgnoreAttributeOrder(true);
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setNormalize(true);
+        XMLUnit.setNormalizeWhitespace(true);
+        XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
+
+        HashMap namespaces = new HashMap();
+        namespaces.put("rapi", "http://marklogic.com/rest-api");
+        namespaces.put("prop", "http://marklogic.com/xdmp/property");
+        namespaces.put("xs",   "http://www.w3.org/2001/XMLSchema");
+        namespaces.put("xsi",  "http://www.w3.org/2001/XMLSchema-instance");
+
+        SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext(namespaces);
+
+        xpather = XMLUnit.newXpathEngine();
+        xpather.setNamespaceContext(namespaceContext);
+				
+        ObjectMapper mapper = new ObjectMapper();
+        
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		InputStreamHandle isHandle = new InputStreamHandle();
+		isHandle.set(inputStream);
+		before = isHandle.toBuffer();
+		strBefore = new String(before);
+		System.out.println("Before: " + strBefore);
+		
+		JsonNode contentBefore = mapper.readValue(strBefore, JsonNode.class);
+		
+		// write doc
+		JSONDocumentManager docMgr = client.newJSONDocumentManager(); 
+		String docId = uri + filename;
+		docMgr.write(docId, isHandle);
+		
+		// read doc
+		docMgr.read(docId, isHandle);
+		isHandle.get();
+		
+		after = isHandle.toBuffer();
+		strAfter = new String(after);
+		System.out.println("After: " + strAfter);
+		
+		JsonNode contentAfter = mapper.readValue(strAfter, JsonNode.class);
+		
+		assertTrue("Buffered JSON document difference", contentBefore.equals(contentAfter));
+		
+	    // release client
+	    client.release();
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18724.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18724.java
new file mode 100644
index 000000000..523b09b6b
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18724.java
@@ -0,0 +1,241 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.AggregateResult;
+import com.marklogic.client.query.KeyValueQueryDefinition;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.query.ValuesDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.ValuesHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug18724 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug18724DB";
+	private static String [] fNames = {"Bug18724DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testDefaultStringSearch() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDefaultStringSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create transaction
+		Transaction transaction1 = client.openTransaction();
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/def-string-search/", transaction1, "XML");
+		}
+		
+		// commit transaction
+		transaction1.commit();
+		
+		// create transaction
+		Transaction transaction2 = client.openTransaction();
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria("0012");
+				
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result']//*[local-name()='highlight'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	
+	public void testDefaultKeyValueSearch() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDefaultKeyValueSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create transaction
+		Transaction transaction1 = client.openTransaction();
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/def-keyvalue-search/", transaction1, "XML");
+		}
+		
+		// commit transaction
+		transaction1.commit();
+		
+		// create transaction
+		Transaction transaction2 = client.openTransaction();
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition
+		KeyValueQueryDefinition querydef = queryMgr.newKeyValueDefinition();
+		querydef.put(queryMgr.newElementLocator(new QName("id")), "0012");
+				
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result']//*[local-name()='highlight'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+	/*public void testDefaultStructuredQueryBuilderSearch() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDefaultStructuredQueryBuilderSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/def-query-builder-search/", "XML");
+		}
+		
+		// create transaction
+		Transaction transaction2 = client.openTransaction();
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition termQuery = qb.term("0012");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(termQuery, resultsHandle, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result']//*[local-name()='highlight'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}*/
+	
+	/*public void testDefaultValuesSearch() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDefaultValuesSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create transaction
+		Transaction transaction1 = client.openTransaction();
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/def-values-search/", transaction1, "XML");
+		}
+		
+		// commit transaction
+		transaction1.commit();
+		
+		// create transaction
+		Transaction transaction2 = client.openTransaction();
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity");
+		queryDef.setAggregate("sum");
+		//queryDef.setName("popularity");
+		
+		// create handle
+		ValuesHandle valuesHandle = new ValuesHandle();
+		queryMgr.values(queryDef, valuesHandle, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		// get the result
+		//Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+        AggregateResult[] agg = valuesHandle.getAggregates();
+        System.out.println(agg.length);
+        int first  = agg[0].get("xs:int", Integer.class);
+        System.out.println(first);
+        
+		//assertXpathEvaluatesTo("1", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		//assertXpathEvaluatesTo("0012", "string(//*[local-name()='result']//*[local-name()='highlight'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}*/
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18736.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18736.java
new file mode 100644
index 000000000..7fd0f0767
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18736.java
@@ -0,0 +1,108 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.Format;
+
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.XpathEngine;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import org.junit.*;
+public class TestBug18736 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug18736DB";
+	private static String [] fNames = {"Bug18736DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug18736() throws XpathException, TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("Running testBug18736");
+		
+		String filename = "constraint1.xml";
+		String docId = "/content/without-xml-ext";
+		//XpathEngine xpathEngine;
+		
+		/*HashMap xpathNS = new HashMap();
+		xpathNS.put("", "http://purl.org/dc/elements/1.1/");
+		SimpleNamespaceContext xpathNsContext = new SimpleNamespaceContext(xpathNS);
+
+		XMLUnit.setIgnoreAttributeOrder(true);
+		XMLUnit.setIgnoreWhitespace(true);
+		XMLUnit.setNormalize(true);
+		XMLUnit.setNormalizeWhitespace(true);
+		XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
+		
+		xpathEngine = XMLUnit.newXpathEngine();
+		xpathEngine.setNamespaceContext(xpathNsContext);*/
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		// create write handle
+		InputStreamHandle writeHandle = new InputStreamHandle();
+
+		// get the file
+		InputStream inputStream = new FileInputStream("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		writeHandle.set(inputStream);
+		
+		// create doc descriptor
+		DocumentDescriptor docDesc = docMgr.newDescriptor(docId); 
+		
+		docMgr.write(docDesc, writeHandle);
+
+		docDesc.setFormat(Format.XML);
+        DOMHandle readHandle = new DOMHandle();
+        docMgr.read(docDesc, readHandle);
+        Document readDoc = readHandle.get();
+        String out = convertXMLDocumentToString(readDoc);
+        System.out.println(out);
+        
+        assertTrue("Unable to read doc", out.contains("0011"));
+        
+        // get xml document for expected result
+        //Document expectedDoc = expectedXMLDocument(filename);
+     		
+     	//assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+                
+		// release client
+	    client.release();	
+	}
+@AfterClass	
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18801.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18801.java
new file mode 100644
index 000000000..d0404d2bc
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18801.java
@@ -0,0 +1,118 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.query.StructuredQueryDefinition;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug18801 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug18801DB";
+	private static String [] fNames = {"Bug18801DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testDefaultFacetValue() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDefaultFacetValue");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/def-facet/", "XML");
+		}
+
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConstraints(builder.constraint("pop",
+				builder.range(builder.elementRangeIndex(new QName("popularity"),
+						builder.rangeType("xs:int")))));
+        
+        // write query options
+        optionsMgr.writeOptions("FacetValueOpt", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("FacetValueOpt", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+
+     	// create query manager
+     	QueryManager queryMgr = client.newQueryManager();
+     				
+     	// create query def
+     	StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("FacetValueOpt");
+     	StructuredQueryDefinition queryFinal = qb.rangeConstraint("pop", Operator.EQ, "5");
+     		
+     	// create handle
+     	DOMHandle resultsHandle = new DOMHandle();
+     	queryMgr.search(queryFinal, resultsHandle);
+     		
+     	// get the result
+     	Document resultDoc = resultsHandle.get();
+     	//System.out.println(convertXMLDocumentToString(resultDoc)); 
+     	
+     	assertXpathEvaluatesTo("pop", "string(//*[local-name()='response']//*[local-name()='facet']//@*[local-name()='name'])", resultDoc);
+     	assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//*[local-name()='facet']/*[local-name()='facet-value']//@*[local-name()='count'])", resultDoc);
+     	
+		// release client
+		client.release();		
+	}
+	@AfterClass	
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18920.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18920.java
new file mode 100644
index 000000000..9f285f9c7
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18920.java
@@ -0,0 +1,110 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.FailedRequestException;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.admin.ServerConfigurationManager.Policy;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.document.XMLDocumentManager;
+import org.junit.*;
+public class TestBug18920 extends BasicJavaClientREST{
+
+	private static String dbName = "Test18920DB";
+	private static String [] fNames = {"Test18920DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBug18920() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testBug18920");
+		
+		String filename = "xml-original.xml";
+		String uri = "/bug18920/";
+		String docId = uri + filename;
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for the server configuration
+		ServerConfigurationManager configMgr = client.newServerConfigManager();
+
+		// read the server configuration from the database
+		configMgr.readConfiguration();
+
+		// require content versions for updates and deletes
+		// use Policy.OPTIONAL to allow but not require versions
+		configMgr.setContentVersionRequests(Policy.REQUIRED);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+		System.out.println("set optimistic locking to required");
+		
+		// create document manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create document descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		// write doc
+		docMgr.write(desc, handle);
+				
+		String docUri = desc.getUri();
+		System.out.println(docUri);
+		
+		String exception = "";
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: Content version required to write document. Server Message: You do not have permission to this method and URL";
+		
+		// update document with no content version
+		try 
+		{
+			docMgr.write(docUri, handle);
+		} catch (FailedRequestException e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// set content version back to none
+		configMgr.setContentVersionRequests(Policy.NONE);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+				
+		// release client
+		client.release();
+	}
+		@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18990.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18990.java
new file mode 100644
index 000000000..53e266a12
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18990.java
@@ -0,0 +1,95 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug18990 extends BasicJavaClientREST {
+
+	private static String dbName = "TestBug18990DB";
+	private static String [] fNames = {"TestBug18990DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug18990() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug18990");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true and server logger to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setServerRequestLogging(true);
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/bug18990/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition valueConstraintQuery1 = qb.valueConstraint("id", "00*2");
+		StructuredQueryDefinition valueConstraintQuery2 = qb.valueConstraint("id", "0??6");
+		StructuredQueryDefinition orFinalQuery = qb.or(valueConstraintQuery1, valueConstraintQuery2);
+		
+		// create handle
+		StringHandle resultsHandle = new StringHandle().withFormat(Format.JSON);
+		queryMgr.search(orFinalQuery, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+	    assertTrue("Result in json is not correct", resultDoc.contains("{\"snippet-format\":\"raw\",\"total\":4,\"start\":1,\"page-length\":10,\"results\":[{\"index\":1,\"uri\":\"/bug18990/constraint5.xml\""));
+		
+	    // turn off server logger
+	    srvMgr.setServerRequestLogging(false);
+	    srvMgr.writeConfiguration();
+	    
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug18993.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18993.java
new file mode 100644
index 000000000..863c21dc6
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug18993.java
@@ -0,0 +1,65 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestBug18993 extends BasicJavaClientREST {
+	
+	private static String dbName = "Bug18993DB";
+	private static String [] fNames = {"Bug18993DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		loadBug18993();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBug18993() throws IOException
+	{
+		System.out.println("Running testBug18993");
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+				
+		StringHandle readHandle = new StringHandle();
+		 
+		String uris[] = {"/a b"};
+		
+		String expectedXML = "a space b";
+		
+	    for (String uri : uris) 
+	    {
+	        System.out.println("uri = " + uri);
+	        docMgr.read(uri, readHandle);
+	        System.out.println();
+	        String strXML = readHandle.toString();
+	        System.out.print(readHandle.toString());
+	        assertTrue("Document is not returned", strXML.contains(expectedXML));
+	        System.out.println();
+	    } 
+		
+		// release client
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+		
+	}
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19016.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19016.java
new file mode 100644
index 000000000..3f7929be4
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19016.java
@@ -0,0 +1,70 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.marklogic.client.query.QueryManager;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19016 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug19016DB";
+	private static String [] fNames = {"Bug19016DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBug19016() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testBug19016");
+		
+		String[] filenames = {"bug19016.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/bug19016/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria("this\"is\"an%33odd string");
+
+		String result = queryMgr.search(querydef, new StringHandle()).get();
+		
+		System.out.println(result);
+		
+		assertTrue("qtext is not correct", result.contains("this\"is\"an%33odd string"));
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19046.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19046.java
new file mode 100644
index 000000000..675dda5a0
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19046.java
@@ -0,0 +1,73 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19046 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug19046DB";
+	private static String [] fNames = {"Bug19046DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19046() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19046");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		        
+        // read non-existent query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	
+        String expectedException = "com.marklogic.client.ResourceNotFoundException: Could not get /config/query/NonExistentOpt";
+		
+		String exception = "";
+     	
+		try
+		{
+			optionsMgr.readOptions("NonExistentOpt", readHandle);
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		System.out.println(exception);
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+     	
+		// release client
+		client.release();		
+	}
+		@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19092.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19092.java
new file mode 100644
index 000000000..8c13e1efd
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19092.java
@@ -0,0 +1,116 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19092 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug19092DB";
+	private static String [] fNames = {"Bug19092DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19092() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19092");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withTerm(builder.term("case-sensitive"));
+        
+        // write query options
+        optionsMgr.writeOptions("DefaultTermOpt", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("DefaultTermOpt", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+     	
+     	assertTrue("Default term is not correct", output.contains("case-sensitive") || output.contains("case-sensitive"));
+     	assertFalse("Weight element exists", output.contains("0.0") || output.contains("0.0"));
+     	assertFalse("Default element exists", output.contains("") || output.contains(""));
+     	
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19092WithJson() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19092WithJson");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withTerm(builder.term("case-sensitive"));
+        
+        // write query options
+        optionsMgr.writeOptions("DefaultTermOpt", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.JSON);
+     	optionsMgr.readOptions("DefaultTermOpt", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+     	
+     	assertTrue("Default term is not correct", output.contains("{\"options\":{\"term\":{\"term-option\":[\"case-sensitive\"]}}}"));
+     	
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19140.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19140.java
new file mode 100644
index 000000000..f047322b6
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19140.java
@@ -0,0 +1,78 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19140 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug19140DB";
+	private static String [] fNames = {"Bug19140DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19140() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19140");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withTransformResults(builder.rawResults());
+        
+        // write query options
+        optionsMgr.writeOptions("RawResultsOpt", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("RawResultsOpt", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+     	
+     	assertTrue("transform-results is incorrect", output.contains("transform-results apply=\"raw\"/"));
+     	assertFalse("preferred-elements is exist", output.contains("preferred-elements/"));
+     	
+		// release client
+		client.release();		
+	}
+	@AfterClass	
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19144.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19144.java
new file mode 100644
index 000000000..d9e7bd943
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19144.java
@@ -0,0 +1,122 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.ValuesDefinition;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19144 extends BasicJavaClientREST {
+
+	private static String dbName = "TestBug19144DB";
+	private static String [] fNames = {"TestBug19144DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19144WithJson() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19144WithJson");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/bug19144/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity", "aggregatesOpt.xml");
+		queryDef.setAggregate("correlation", "covariance");
+		queryDef.setName("pop-rate-tups");
+		
+		// create handle
+		StringHandle resultHandle = new StringHandle().withFormat(Format.JSON);
+		queryMgr.tuples(queryDef, resultHandle);
+		
+		String result = resultHandle.get();
+		
+		System.out.println(result);
+		
+		assertEquals("{", result.substring(0, 1));
+        		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19144WithXml() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19144WithXml");
+		
+		String[] filenames = {"aggr1.xml", "aggr2.xml", "aggr3.xml", "aggr4.xml", "aggr5.xml"};
+		String queryOptionName = "aggregatesOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/bug19144/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		ValuesDefinition queryDef = queryMgr.newValuesDefinition("popularity", "aggregatesOpt.xml");
+		queryDef.setAggregate("correlation", "covariance");
+		queryDef.setName("pop-rate-tups");
+		
+		// create handle
+		StringHandle resultHandle = new StringHandle().withFormat(Format.XML);
+		queryMgr.tuples(queryDef, resultHandle);
+		
+		String result = resultHandle.get();
+		
+		System.out.println(result);
+		
+		assertEquals("<", result.substring(0, 1));
+        		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19389.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19389.java
new file mode 100644
index 000000000..e7528b03e
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19389.java
@@ -0,0 +1,79 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug19389 extends BasicJavaClientREST {
+
+	private static String dbName = "Bug19389DB";
+	private static String [] fNames = {"Bug19389DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19389() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug19389");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// set error format to JSON
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.setErrorFormat(Format.JSON);
+		srvMgr.writeConfiguration();
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		        
+        // read non-existent query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	
+        String expectedException = "com.marklogic.client.ResourceNotFoundException: Could not get /config/query/NonExistentOpt";
+		
+		String exception = "";
+     	
+		try
+		{
+			optionsMgr.readOptions("NonExistentOpt", readHandle);
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		System.out.println(exception);
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+     	
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug19443.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19443.java
new file mode 100644
index 000000000..c11be6011
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug19443.java
@@ -0,0 +1,79 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+
+import javax.xml.namespace.QName;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestBug19443 extends BasicJavaClientREST {
+
+	private static String dbName = "TestBug19443DB";
+	private static String [] fNames = {"TestBug19443DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug19443() throws FileNotFoundException, XpathException
+	{	
+		System.out.println("Running testBug19443");
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConstraints(builder.constraint("geoElemChild", builder.geospatial(builder.elementChildGeospatialIndex(new QName("foo"), new QName("bar")), "type=long-lat-point")));
+               
+        // write query options
+        optionsMgr.writeOptions("ElementChildGeoSpatialIndex", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("ElementChildGeoSpatialIndex", readHandle);
+	    String output = readHandle.get();
+	    
+	    String outputTrimmed = output.replaceAll("\n", "");
+	    outputTrimmed = outputTrimmed.replaceAll(" ", "");
+	    
+	    System.out.println(output);
+	    
+	    assertTrue("option is not correct", outputTrimmed.contains("type=long-lat-point") || outputTrimmed.contains("type=long-lat-point"));
+	                    
+		// release client
+	    client.release();	
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug20979.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug20979.java
new file mode 100644
index 000000000..b848bba32
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug20979.java
@@ -0,0 +1,86 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug20979 extends BasicJavaClientREST {
+
+	private static String dbName = "TestBug20979DB";
+	private static String [] fNames = {"TestBug20979DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug20979() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug20979");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "wordConstraintWithElementAndAttributeIndexPlanOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/word-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:1945 OR inprice:12");
+
+		// create handle
+		SearchHandle resultsHandle = new SearchHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		//Document resultDoc = resultsHandle.getPlan();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		String strPlan = resultsHandle.getPlan(new StringHandle()).get();
+		System.out.println(strPlan);
+		
+		assertTrue("string is not matched", strPlan.contains("qry:result estimate=\"3\""));
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug21159.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug21159.java
new file mode 100644
index 000000000..25bce19e5
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug21159.java
@@ -0,0 +1,160 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.CountedDistinctValue;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+import com.marklogic.client.query.Tuple;
+import com.marklogic.client.query.ValuesDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.TuplesHandle;
+import com.marklogic.client.io.ValuesHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug21159 extends BasicJavaClientREST {
+
+	private static String dbName = "TestRawCombinedQueryDB";
+	private static String [] fNames = {"TestRawCombinedQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	  
+    	addRangeElementIndex(dbName, "string", "", "grandchild", "http://marklogic.com/collation/");
+    	addRangeElementIndex(dbName, "double", "", "double");
+    	addRangeElementIndex(dbName, "int", "", "int");
+    	addRangeElementIndex(dbName, "string", "", "string", "http://marklogic.com/collation/");
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testBug21159Tuples() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug21159Tuples");
+		
+		String[] filenames = {"tuples-test1.xml", "tuples-test2.xml", "tuples-test3.xml", "tuples-test4.xml", "lexicon-test1.xml","lexicon-test2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/LexiconOptions.xml");
+		
+		String combinedQuery = convertFileToString(file);
+				
+		RawCombinedQueryDefinition rawCombinedQueryDefinition;
+		QueryManager queryMgr = client.newQueryManager();
+		rawCombinedQueryDefinition = queryMgr.newRawCombinedQueryDefinition(new StringHandle(combinedQuery).withMimetype("application/xml"));
+		
+		StringHandle stringResults = null;
+		ValuesDefinition vdef = queryMgr.newValuesDefinition("grandchild");
+		
+		vdef.setQueryDefinition(rawCombinedQueryDefinition);
+		
+		stringResults = queryMgr.tuples(vdef, new StringHandle());
+		System.out.println(stringResults.get());
+		
+		ValuesHandle valuesResults = queryMgr.values(vdef,new ValuesHandle());
+		
+		assertFalse(valuesResults.getMetrics().getTotalTime() == -1);
+
+		CountedDistinctValue[] values = valuesResults.getValues();
+		
+		assertNotNull(values);
+
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testBug21159Values() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+{	
+	System.out.println("Running testBug21159Values");
+	
+	String[] filenames = {"tuples-test1.xml", "tuples-test2.xml", "tuples-test3.xml", "tuples-test4.xml", "lexicon-test1.xml","lexicon-test2.xml"};
+
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+	
+	// set query option validation to true
+	ServerConfigurationManager srvMgr = client.newServerConfigManager();
+	srvMgr.readConfiguration();
+	srvMgr.setQueryOptionValidation(true);
+	srvMgr.writeConfiguration();
+			
+	// write docs
+	for(String filename : filenames)
+	{
+		writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+	}
+	
+	// get the combined query
+    File file = new File("src/junit/com/marklogic/javaclient/combined/LexiconOptions.xml");
+	
+	String combinedQuery = convertFileToString(file);
+			
+	RawCombinedQueryDefinition rawCombinedQueryDefinition;
+	QueryManager queryMgr = client.newQueryManager();
+	rawCombinedQueryDefinition = queryMgr.newRawCombinedQueryDefinition(new StringHandle(combinedQuery).withMimetype("application/xml"));
+	
+	StringHandle stringResults = null;
+	ValuesDefinition vdef = queryMgr.newValuesDefinition("n-way");
+	
+	vdef.setQueryDefinition(rawCombinedQueryDefinition);
+	
+	stringResults = queryMgr.tuples(vdef, new StringHandle());
+	System.out.println(stringResults.get());
+	
+	TuplesHandle tuplesResults = queryMgr.tuples(vdef,
+			new TuplesHandle());
+	Tuple[] tuples = tuplesResults.getTuples();
+	assertNotNull(tuples);
+
+	// release client
+	client.release();		
+}
+
+@AfterClass
+public static void tearDown() throws Exception
+{
+	System.out.println("In tear down");
+	tearDownJavaRESTServer(dbName, fNames, restServerName);
+	
+}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug21183.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug21183.java
new file mode 100644
index 000000000..a6f363bf9
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug21183.java
@@ -0,0 +1,96 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.XMLStreamReaderHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug21183 extends BasicJavaClientREST {
+
+	private static String dbName = "TestBug21183DB";
+	private static String [] fNames = {"TestBug21183DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug21183() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug21183");
+		
+		String[] filenames = {"bug21183.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/bug-21183/", "XML");
+		}
+		
+		// set query option
+		setQueryOption(client, "bug21183Opt.xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("bug21183Opt.xml");
+		querydef.setCriteria("a");
+		
+		// create result handle
+		SearchHandle resultsHandle = queryMgr.search(querydef, new SearchHandle()); 
+		
+		String resultDoc1 = "";
+		
+		// get the result
+		for (MatchDocumentSummary result : resultsHandle.getMatchResults()) 
+		{
+			for (Document s : result.getSnippets())
+			resultDoc1 = convertXMLDocumentToString(s);	
+			System.out.println(resultDoc1);
+			//Commenting as per Update from Bug 23788
+			//assertTrue("Returned doc from SearchHandle has no namespace", resultDoc1.contains(""));
+			assertTrue("Returned doc from SearchHandle has no attribute", resultDoc1.contains("a"));
+			System.out.println();
+		} 
+		
+		XMLStreamReaderHandle shandle = queryMgr.search(querydef, new XMLStreamReaderHandle());
+		String resultDoc2 = shandle.toString();
+		System.out.println(resultDoc2);
+		assertTrue("Returned doc from XMLStreamReaderHandle has no namespace", resultDoc2.contains(""));
+		assertTrue("Returned doc from XMLStreamReaderHandle has no attribute", resultDoc2.contains("a"));
+			    		
+		// release client
+		client.release();		
+	}
+	
+	public void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBug22037.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBug22037.java
new file mode 100644
index 000000000..a14848d46
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBug22037.java
@@ -0,0 +1,82 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestBug22037 extends BasicJavaClientREST {
+
+	
+	private static String dbName = "TestBug22037DB";
+	private static String [] fNames = {"TestBug22037DB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testBug22037() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug22037");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "rangeConstraintIntOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/range-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+				
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition rangeQuery = qb.range(qb.element("popularity"), "xs:int", Operator.GE, 4);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(rangeQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkReadSample1.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkReadSample1.java
new file mode 100644
index 000000000..f350e42a7
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkReadSample1.java
@@ -0,0 +1,336 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+
+import java.util.HashMap;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.extra.jdom.*;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.JAXBHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DOMHandle;
+
+import com.marklogic.client.io.JacksonHandle;
+
+
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.FailedRequestException;
+
+
+
+import javax.xml.transform.dom.DOMSource;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.w3c.dom.Document;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/*
+ * This test is designed to to test simple bulk reads with different types of Managers and different content type like JSON,text,binary,XMl by passing set of uris
+ * 
+ *  TextDocumentManager
+ *  XMLDocumentManager
+ *  BinaryDocumentManager
+ *  JSONDocumentManager
+ *  GenericDocumentManager
+ */
+
+
+
+public class TestBulkReadSample1 extends BasicJavaClientREST  {
+
+	private static final int BATCH_SIZE=100;
+	private static final String DIRECTORY ="/bulkread/";
+	private static String dbName = "TestBulkReadSampleDB";
+	private static String [] fNames = {"TestBulkReadSampleDB-1"};
+	private static String restServerName = "TestBulkReadSample-RESTServer";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+    @BeforeClass
+	public static void setUp() throws Exception 
+	{
+	   System.out.println("In setup");
+	   setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+       setupAppServicesConstraint(dbName);	  
+
+	}
+	
+  @Before  public void testSetup() throws Exception
+  {
+	  // create new connection for each test below
+	  client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+  }
+    @After
+    public  void testCleanUp() throws Exception
+    {
+    	System.out.println("Running CleanUp script");	
+    	// release client
+    	client.release();
+
+    	
+    }
+    /*
+     * 
+     * Use StringHandle to load 102 text documents using bulk write set.
+     * Test Bulk Read to see you can read all the documents?
+     */
+	@Test  
+	public void testReadMultipleTextDoc() 
+	  {
+		int count=1;
+	    TextDocumentManager docMgr = client.newTextDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	    
+	    for(int i =0;i<102;i++){
+	      writeset.add(DIRECTORY+"foo"+i+".txt", new StringHandle().with("This is so foo"+i));
+	      if(count%BATCH_SIZE == 0){
+	    	  docMgr.write(writeset);
+	    	  writeset = docMgr.newWriteSet();
+	    	}
+	      count++;
+	    }
+	    if(count%BATCH_SIZE > 0){
+	    	  docMgr.write(writeset);
+	    	    	}
+	    String uris[] = new String[102];
+	    for(int i =0;i<102;i++){
+	    uris[i]=DIRECTORY+"foo"+i+".txt";
+	    }
+	    count=0;
+	    DocumentPage page = docMgr.read(uris);
+	    while(page.hasNext()){
+	    	DocumentRecord rec = page.next();
+	    	validateRecord(rec,Format.TEXT);
+	    	count++;
+	    }
+	    assertEquals("document count", 102,count); 
+	    
+	  }
+	/*
+	* This test uses DOMHandle to do bulk write 102 xml documents, and does a bulk read from database.
+    * Verified by reading individual documents
+    */
+@Test  
+	public void testReadMultipleXMLDoc() throws Exception  
+	  {
+		int count=1;
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	    HashMap map= new HashMap();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	    for(int i =0;i<102;i++){
+	    	
+		    writeset.add(DIRECTORY+"foo"+i+".xml", new DOMHandle(getDocumentContent("This is so foo"+i)));
+		    map.put(DIRECTORY+"foo"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is so foo"+i)));
+		    if(count%BATCH_SIZE == 0){
+		    	  docMgr.write(writeset);
+		    	  writeset = docMgr.newWriteSet();
+		    	}
+		      count++;
+	    }
+	    if(count%BATCH_SIZE > 0){
+	    	docMgr.write(writeset);
+	 	 }
+		 String uris[] = new String[102];
+		 for(int i =0;i<102;i++){
+		    uris[i]=DIRECTORY+"foo"+i+".xml";
+		  }
+		  count=0;
+		  DocumentPage page = docMgr.read(uris);
+		  DOMHandle dh = new DOMHandle();
+		  while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		    	validateRecord(rec,Format.XML);
+		    	rec.getContent(dh);
+		    	assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+		    	count++;
+		  }
+		  
+		 assertEquals("document count", 102,count); 
+	    
+	  }
+	/*
+	 * This test uses FileHandle to bulkload 102 binary documents,test bulk read from database.
+     * 
+	 */
+	@Test 
+	public void testReadMultipleBinaryDoc() throws Exception  
+	  {
+		 String docId[] = {"Sega-4MB.jpg"};
+		 int count=1;
+		 BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileHandle h1 = new FileHandle(file1);
+		 for(int i =0;i<102;i++){
+			    writeset.add(DIRECTORY+"binary"+i+".jpg", h1);
+			    if(count%BATCH_SIZE == 0){
+			    	  docMgr.write(writeset);
+			    	  writeset = docMgr.newWriteSet();
+			    	}
+			      count++;
+		    }
+		    if(count%BATCH_SIZE > 0){
+		    	docMgr.write(writeset);
+		 	 }
+		    String uris[] = new String[102];
+			 for(int i =0;i<102;i++){
+			    uris[i]=DIRECTORY+"binary"+i+".jpg";
+			  }
+			  count=0;
+			  FileHandle rh = new FileHandle();
+			  DocumentPage page = docMgr.read(uris);
+			  while(page.hasNext()){
+			    	DocumentRecord rec = page.next();
+			    	validateRecord(rec,Format.BINARY);
+			    	rec.getContent(rh);
+			    	assertEquals("Content length :",file1.length(),rh.get().length());
+			    	count++;
+			  }
+			 assertEquals("document count", 102,count); 
+			//Testing the multiple same uris will not read multiple records 
+			for(int i =0;i<102;i++){
+				    uris[i]=DIRECTORY+"binary"+12+".jpg";
+				  }
+				  count=0;
+				  page = docMgr.read(uris);
+				  while(page.hasNext()){
+				    	DocumentRecord rec = page.next();
+				    	validateRecord(rec,Format.BINARY);
+				    	count++;
+				  }
+				 assertEquals("document count", 1,count); 
+	    }
+
+/*
+	 * Load 102 JSON documents using JacksonHandle, do a bulk read. 
+     * Verify by reading individual documents
+	 * This test has a bug logged in github with tracking Issue#33
+ */
+	@Test
+	public void testWriteMultipleJSONDocs() throws Exception  
+	  {
+		 int count=1;	 
+ 		 JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 
+		 HashMap map= new HashMap();
+		 
+		 for(int i =0;i<102;i++){
+		 JsonNode jn = new ObjectMapper().readTree("{\"animal"+i+"\":\"dog"+i+"\", \"says\":\"woof\"}");
+		 JacksonHandle jh = new JacksonHandle();
+		 jh.set(jn);
+		 writeset.add(DIRECTORY+"dog"+i+".json",jh);
+		 map.put(DIRECTORY+"dog"+i+".json", jn.toString());
+		 if(count%BATCH_SIZE == 0){
+	    	  docMgr.write(writeset);
+	    	  writeset = docMgr.newWriteSet();
+	    	}
+	      count++;
+//	      System.out.println(jn.toString());
+		 }
+		 if(count%BATCH_SIZE > 0){
+		 docMgr.write(writeset);
+		 }
+		 String uris[] = new String[102];
+		 for(int i =0;i<102;i++){
+			 uris[i]=DIRECTORY+"dog"+i+".json";
+		 }
+		 count=0;
+		 DocumentPage page = docMgr.read(uris);
+		 DocumentRecord rec;
+		 JacksonHandle jh = new JacksonHandle();
+		 while(page.hasNext()){
+	    	rec = page.next();
+	    	validateRecord(rec,Format.JSON);
+	    	rec.getContent(jh);
+	    	assertEquals("Comparing the content :",map.get(rec.getUri()),jh.get().toString());
+	    	count++;
+	  }
+//		 validateRecord(rec,Format.JSON);
+	 assertEquals("document count", 102,count); 
+   
+
+	    }
+/*
+ * This test uses GenericManager to load all different document types
+ * This test has a bug logged in github with tracking Issue#33
+ * 
+ */
+@Test 
+	public void testWriteGenericDocMgr() throws Exception  
+	  {
+		
+		GenericDocumentManager docMgr = client.newDocumentManager();
+		 int countXML=0,countJson=0,countJpg=0,countTEXT=0;
+		 String uris[] = new String[102];
+		 for(int i =0;i<99;){
+		    uris[i]=DIRECTORY+"foo"+i+".xml";
+		    i++;
+		    uris[i]=DIRECTORY+"foo"+i+".txt";
+		    i++;
+		    uris[i]=DIRECTORY+"binary"+i+".jpg";
+		    i++;
+		    uris[i]=DIRECTORY+"dog"+i+".json";
+		    i++;
+		  }
+//		 for(String uri:uris){System.out.println(uri);}
+		  DocumentPage page = docMgr.read(uris);
+		  if(!page.hasNext()){
+			testReadMultipleTextDoc();
+			testReadMultipleXMLDoc();
+			testReadMultipleBinaryDoc();
+			testWriteMultipleJSONDocs();
+			page = docMgr.read(uris);
+			}
+		  while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		     	switch(rec.getFormat())
+		    	{
+		    	case XML: countXML++; break;
+		    	case TEXT: countTEXT++;break;
+		    	case JSON: countJson++; break;
+		    	case BINARY: countJpg++; break;
+		    	default :
+		    		break;
+		    	}
+		    	validateRecord(rec,rec.getFormat());
+		     }
+		  System.out.println("xml :"+countXML+"TXT :"+countTEXT+" json :"+countJpg+" "+countJson);
+		 assertEquals("xml document count", 25,countXML);
+		 assertEquals("text document count", 25,countTEXT);
+		 assertEquals("binary document count", 25,countJpg);
+		 assertEquals("Json document count", 25,countJson);
+	    }
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+	System.out.println("In tear down" );
+	tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+
+  public void validateRecord(DocumentRecord record,Format type) {
+	       
+	        assertNotNull("DocumentRecord should never be null", record);
+	        assertNotNull("Document uri should never be null", record.getUri());
+	        assertTrue("Document uri should start with " + DIRECTORY, record.getUri().startsWith(DIRECTORY));
+	        assertEquals("All records are expected to be in same format", type, record.getFormat());
+	        
+	       }
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata1.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata1.java
new file mode 100644
index 000000000..47806ae32
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata1.java
@@ -0,0 +1,327 @@
+/**
+ * 
+ */
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Calendar;
+
+import javax.xml.transform.dom.DOMSource;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.JacksonHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+
+/**
+ * @author skottam
+ *This test is designed to add default meta data bulk writes with different types of Managers and different content type like JSON,text,binary,XMl
+ * 
+ *  TextDocumentManager
+ *  XMLDocumentManager
+ *  BinaryDocumentManager
+ *  JSONDocumentManager
+ *  GenericDocumentManager
+ *  
+ */
+public class TestBulkWriteMetadata1  extends BasicJavaClientREST {
+	
+	private static String dbName = "TestBulkWriteDefaultMetadataDB";
+	private static String [] fNames = {"TestBulkWriteDefaultMetadataDB-1"};
+	private static String restServerName = "TestBulkWriteDefaultMetadata-RESTServer";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		  System.out.println("In Setup");
+		  setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+		  createRESTUser("app-user", "password", "rest-writer","rest-reader" );
+		
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+		System.out.println("In tear down" );
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		deleteRESTUser("app-user");
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		// create new connection for each test below
+		  client = DatabaseClientFactory.newClient("localhost", restPort, "app-user", "password", Authentication.DIGEST);
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+		System.out.println("Running clear script");	
+    	// release client
+    	client.release();
+	}
+	
+	public DocumentMetadataHandle setMetadata(){
+		  // create and initialize a handle on the metadata
+		DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    metadataHandle.getCollections().addAll("my-collection1","my-collection2");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    return	metadataHandle;
+	}
+	public void validateMetadata(DocumentMetadataHandle mh){
+
+	    // get metadata values
+	    DocumentProperties properties = mh.getProperties();
+	    DocumentPermissions permissions = mh.getPermissions();
+	    DocumentCollections collections = mh.getCollections();
+	    
+	    // Properties
+	    String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:3|rest-reader:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|my-collection1|my-collection2|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	}
+
+	@Test  
+	public void testWriteMultipleTextDocWithDefaultMetadata() 
+	  {
+		DocumentMetadataHandle mh1,mh2;
+		 String docId[] = {"/foo/test/myFoo1.txt","/foo/test/myFoo2.txt","/foo/test/myFoo3.txt"};
+	    
+	    TextDocumentManager docMgr = client.newTextDocumentManager();
+	         
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	 // put metadata
+	    DocumentMetadataHandle mh = setMetadata();
+	    
+	    writeset.addDefault(mh);
+	    writeset.add(docId[0], new StringHandle().with("This is so foo1"));
+	    writeset.add(docId[1], new StringHandle().with("This is so foo2"));
+	    writeset.add(docId[2], new StringHandle().with("This is so foo3"));
+	    docMgr.write(writeset);
+	    DocumentPage page = docMgr.read(docId);
+	    
+	    while(page.hasNext()){
+	    	DocumentRecord rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh);
+	    	validateMetadata(mh);
+	    }
+	    validateMetadata(mh);
+	  }
+	@Test  
+	public void testWriteMultipleXMLDocWithDefaultMetadata() throws Exception  
+	  {  
+	    String docId[] = {"/foo/test/Foo1.xml","/foo/test/Foo2.xml","/foo/test/Foo3.xml"};
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	 // put metadata
+	    DocumentMetadataHandle mh = setMetadata();
+	    
+	    writeset.addDefault(mh); 
+	    writeset.add(docId[0], new DOMHandle(getDocumentContent("This is so foo1")));
+	    writeset.add(docId[1], new DOMHandle().with(getDocumentContent("This is so foo2")));
+	    writeset.add(docId[2], new DOMHandle().with(getDocumentContent("This is so foo3")));
+	    
+	    docMgr.write(writeset);
+	    
+	    DocumentPage page = docMgr.read(docId);
+	    
+	    while(page.hasNext()){
+	    	DocumentRecord rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh);
+	    	validateMetadata(mh);
+	    }
+	    validateMetadata(mh);
+	  }
+	@Test 
+	public void testWriteMultipleBinaryDocWithDefaultMetadata() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		 BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		 DocumentMetadataHandle mh = setMetadata();
+		    
+		 writeset.addDefault(mh);
+		 File file1= null,file2=null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileHandle handle1 = new FileHandle(file1);
+		 writeset.add("/1/"+docId[0],handle1.withFormat(Format.BINARY));
+		 writeset.add("/2/"+docId[0],handle1.withFormat(Format.BINARY));
+		 file2 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[1]);
+		 FileHandle handle2 = new FileHandle(file2);
+		 writeset.add("/1/"+docId[1],handle2.withFormat(Format.BINARY));
+		 writeset.add("/2/"+docId[1],handle2.withFormat(Format.BINARY));
+		  
+		 docMgr.write(writeset);
+		 String uris[] = new String[102];
+		 int j=0;
+		 for(int i =1;i<3;i++){
+		    uris[i]="/"+i+"/"+docId[j];
+		    uris[i]="/"+i+"/"+docId[j+1];
+		  }
+		 DocumentPage page = docMgr.read(uris);
+		    
+		    while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		    	docMgr.readMetadata(rec.getUri(), mh);
+		    	System.out.println(rec.getUri());
+		    	validateMetadata(mh);
+		    }
+		    validateMetadata(mh);
+	    }
+
+	@Test
+	public void testWriteMultipleJSONDocsWithDefaultMetadata() throws Exception  
+	  {
+		 String docId[] = {"/a.json","/b.json","/c.json"};
+         String json1 = new String("{\"animal\":\"dog\", \"says\":\"woof\"}");
+         String json2 = new String("{\"animal\":\"cat\", \"says\":\"meow\"}");
+         String json3 =  new String("{\"animal\":\"rat\", \"says\":\"keek\"}");
+ 		 Reader strReader = new StringReader(json1);
+		 JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		 DocumentMetadataHandle mh = setMetadata();
+		    
+		 writeset.addDefault(mh);
+		 writeset.add(docId[0],new ReaderHandle(strReader).withFormat(Format.JSON));
+		 writeset.add(docId[1],new ReaderHandle(new StringReader(json2)));
+		 writeset.add(docId[2],new ReaderHandle(new StringReader(json3)));
+		  
+		 docMgr.write(writeset);
+		 
+		 DocumentPage page = docMgr.read(docId);
+		    
+		    while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		    	docMgr.readMetadata(rec.getUri(), mh);
+		    	System.out.println(rec.getUri());
+		    	validateMetadata(mh);
+		    }
+		    validateMetadata(mh);
+	    }
+	@Test 
+	public void testWriteGenericDocMgrWithDefaultMetadata() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		GenericDocumentManager docMgr = client.newDocumentManager();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		 DocumentMetadataHandle mh = setMetadata();
+		    
+		 writeset.addDefault(mh);
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileInputStream fis = new FileInputStream(file1);
+		 InputStreamHandle handle1 = new InputStreamHandle(fis);
+		 handle1.setFormat(Format.BINARY);
+		 
+		 writeset.add("/generic/Pandakarlino.jpg",handle1);
+		 
+	     JacksonHandle jh = new JacksonHandle();
+	     ObjectMapper objM = new ObjectMapper();
+	     JsonNode jn = objM.readTree(new String("{\"animal\":\"dog\", \"says\":\"woof\"}"));
+	     jh.set(jn);
+	     jh.setFormat(Format.JSON);
+	     
+	     writeset.add("/generic/dog.json",jh);
+	     
+	     String foo1 = "This is foo1 of byte Array";
+	     byte[] ba = foo1.getBytes();
+	     BytesHandle bh = new BytesHandle(ba);
+	     bh.setFormat(Format.TEXT);
+	     
+	     writeset.add("/generic/foo1.txt",bh);
+	     
+	     DOMSource ds = new DOMSource(getDocumentContent("This is so foo1"));
+	     SourceHandle sh = new SourceHandle();
+	     sh.set(ds);
+	     sh.setFormat(Format.XML);
+	    
+	     writeset.add("/generic/foo.xml",sh);
+	     
+		 docMgr.write(writeset);
+	     
+		 DocumentPage page = docMgr.read("/generic/Pandakarlino.jpg","/generic/dog.json","/generic/foo1.txt","/generic/foo.xml");
+		    
+		    while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		    	docMgr.readMetadata(rec.getUri(), mh);
+		    	System.out.println(rec.getUri());
+		    	validateMetadata(mh);
+		    }
+		    validateMetadata(mh);
+	    }
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata2.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata2.java
new file mode 100644
index 000000000..f03215454
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadata2.java
@@ -0,0 +1,552 @@
+/**
+ * 
+ */
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Calendar;
+
+import javax.xml.transform.dom.DOMSource;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.JacksonHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+
+/**
+ * @author skottam
+ * This test is test the DocumentWriteSet function 
+ * public DocumentWriteSet add(String uri, DocumentMetadataWriteHandle metadataHandle);
+ * This test intention is to test the system default , request wide,  and document specific update to metadata will overwrite the existing metadata
+ * setup: create a usr1 with system level meta data as default
+ * client make a connection with usr1 to do bulk loading 
+ * load first set of documents without default meta data and check documents get defaults from usr defaults
+ * load second set of documents where default metadata is set in the middle to see documents at the begining has old defaults and later have latest
+ * load third set of documents with defaultset and do a document specific metadata update and check that is updated.
+ * 
+ */
+public class TestBulkWriteMetadata2 extends  BasicJavaClientREST{
+
+	private static String dbName = "TestBulkWriteDefaultMetadataDB2";
+	private static String [] fNames = {"TestBulkWriteDefaultMetadataDB-2"};
+	private static String restServerName = "TestBulkWriteDefaultMetadata2-RESTServer";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		  System.out.println("In Setup");
+		  setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+		  createRESTUser("app-user", "password","rest-writer","rest-reader"  );
+		  createRESTUserWithPermissions("usr1", "password",getPermissionNode("eval",Capability.READ),getCollectionNode("http://permission-collections/"), "rest-writer","rest-reader" );
+		  setMaintainLastModified(dbName, true);
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+		System.out.println("In tear down" );
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		deleteRESTUser("app-user");
+		deleteRESTUser("usr1");
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		// create new connection for each test below
+		  client = DatabaseClientFactory.newClient("localhost", restPort, "usr1", "password", Authentication.DIGEST);
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+		System.out.println("Running clear script");	
+    	// release client
+    	client.release();
+	}
+	
+	public DocumentMetadataHandle setMetadata(){
+		  // create and initialize a handle on the metadata
+		DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    metadataHandle.getCollections().addAll("my-collection1","my-collection2");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    return	metadataHandle;
+	}
+	public void validateMetadata(DocumentMetadataHandle mh){
+
+	    // get metadata values
+	    DocumentProperties properties = mh.getProperties();
+	    DocumentPermissions permissions = mh.getPermissions();
+	    DocumentCollections collections = mh.getCollections();
+	    
+	    // Properties
+	   // String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    boolean result = actualProperties.contains("size:6|");
+	    assertTrue("Document properties count", result);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    System.out.println(actualPermissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|my-collection1|my-collection2|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	}
+	public void validateDefaultMetadata(DocumentMetadataHandle mh){
+
+	    // get metadata values
+	    DocumentProperties properties = mh.getProperties();
+	    DocumentPermissions permissions = mh.getPermissions();
+	    DocumentCollections collections = mh.getCollections();
+	    
+	    // Properties
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    boolean result =actualProperties.contains("size:1|");
+	    System.out.println(actualProperties +result);
+	    assertTrue("Document default last modified properties count1?", result);
+	   
+	    
+	    // Permissions
+	    
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|eval:[READ]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	   	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:1|http://permission-collections/|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+//	    System.out.println(actualPermissions);
+	}
+	@Test  
+	public void testWriteMultipleTextDocWithDefaultMetadata2() 
+	  {
+		DocumentMetadataHandle mh1,mh2;
+		 String docId[] = {"/foo/test/myFoo1.txt","/foo/test/myFoo2.txt","/foo/test/myFoo3.txt",
+				 			"/foo/test/myFoo4.txt","/foo/test/myFoo5.txt","/foo/test/myFoo6.txt",
+				 			"/foo/test/myFoo7.txt","/foo/test/myFoo8.txt","/foo/test/myFoo9.txt"};
+	    
+	    TextDocumentManager docMgr = client.newTextDocumentManager();
+	         
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	    
+	    writeset.add(docId[0], new StringHandle().with("This is so foo1"));
+	    writeset.add(docId[1], new StringHandle().with("This is so foo2"));
+	    writeset.add(docId[2], new StringHandle().with("This is so foo3"));
+	    docMgr.write(writeset);
+	   //Default system property document set
+	    System.out.println("Assert if document set doesnt show default properties");
+	    DocumentPage page = docMgr.read(docId);
+	    mh1=new DocumentMetadataHandle();
+	    while(page.hasNext()){
+	    	DocumentRecord rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh1);
+	    	validateDefaultMetadata(mh1);
+	    }
+	    validateDefaultMetadata(mh1);
+	  
+	    //Adding document specific properties in document set2
+	   
+	    System.out.println("Assert if document 5 show default properties");
+	        	
+	    	writeset =docMgr.newWriteSet();
+		 // put metadata
+		    mh2 = setMetadata();
+		    
+		    writeset.add(docId[3], new StringHandle().with("This is so foo4"));
+		    writeset.add(docId[4],mh2, new StringHandle().with("This is so foo5"));
+		    writeset.add(docId[5], new StringHandle().with("This is so foo6"));
+		    docMgr.write(writeset);
+		     
+		    
+		    page = docMgr.read(docId[4]);
+		    mh2=new DocumentMetadataHandle();
+		    DocumentRecord rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh2);
+		    validateMetadata(mh2);
+		    page = docMgr.read(docId[3]);
+		    rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh2);
+		    validateDefaultMetadata(mh2);
+		    page = docMgr.read(docId[5]);
+		    rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh2);
+		    validateDefaultMetadata(mh2);
+		    
+		    System.out.println("Assert if documents 8 and 9 show default properties and if 7 doesnt show default");
+		    
+		    writeset =docMgr.newWriteSet();
+		    // put metadata
+		    mh2 = setMetadata();
+			    
+		    writeset.add(docId[6], new StringHandle().with("This is so foo4"));
+		    writeset.addDefault(mh2);
+		    writeset.add(docId[7], new StringHandle().with("This is so foo5"));
+		    writeset.add(docId[8], new StringHandle().with("This is so foo6"));
+		    docMgr.write(writeset);
+			
+			page = docMgr.read(docId[6]);
+			mh2=new DocumentMetadataHandle();
+			rec = page.next();
+			docMgr.readMetadata(rec.getUri(), mh2);
+			validateDefaultMetadata(mh2);
+			    
+			page = docMgr.read(docId[7]);
+			rec = page.next();
+			docMgr.readMetadata(rec.getUri(), mh2);
+			validateMetadata(mh2);
+			    
+			 page = docMgr.read(docId[8]);
+			 rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh2);
+			 validateMetadata(mh2);
+			 
+			 
+	  }
+	@Test  
+	public void testWriteMultipleXMLDocWithDefaultMetadata2() throws Exception  
+	  {  
+		// put metadata
+	    DocumentMetadataHandle mh1,mh2;
+	    String docId[] = {"/foo/test/Foo1.xml","/foo/test/Foo2.xml","/foo/test/Foo3.xml",
+	    					"/foo/test/Foo4.xml","/foo/test/Foo5.xml","/foo/test/Foo6.xml",
+	    					"/foo/test/Foo7.xml","/foo/test/Foo8.xml","/foo/test/Foo8.xml"};
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	   
+	    DocumentDescriptor docdisc = docMgr.newDescriptor("test1");
+	    	    
+	    writeset.add(docdisc, new DOMHandle(getDocumentContent("This is so foo1")));
+	    writeset.add(docId[1], new DOMHandle().with(getDocumentContent("This is so foo2")));
+	    writeset.add(docId[2], new DOMHandle().with(getDocumentContent("This is so foo3")));
+	    
+	    docMgr.write(writeset);
+	    	    
+	    DocumentPage page = docMgr.read(docId);
+	    DocumentRecord rec;
+	    mh1 = new DocumentMetadataHandle();
+	    while(page.hasNext()){
+	    	rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh1);
+	    	validateDefaultMetadata(mh1);
+	    }
+	    validateDefaultMetadata(mh1);
+	 
+	    // put metadata
+	    mh2 = setMetadata();
+	    writeset =docMgr.newWriteSet();
+	    
+	    writeset.add(docId[3], new DOMHandle(getDocumentContent("This is so foo4")));
+	    writeset.addDefault(mh2);
+	    writeset.add(docId[4], new DOMHandle().with(getDocumentContent("This is so foo5")));
+	    writeset.add(docId[5], new DOMHandle().with(getDocumentContent("This is so foo6")));
+	    docMgr.write(writeset);
+	    
+	    page = docMgr.read(docId[3]);
+		mh2=new DocumentMetadataHandle();
+		rec = page.next();
+		docMgr.readMetadata(rec.getUri(), mh2);
+		validateDefaultMetadata(mh2);
+		    
+		page = docMgr.read(docId[4]);
+		rec = page.next();
+		docMgr.readMetadata(rec.getUri(), mh2);
+		validateMetadata(mh2);
+		    
+		 page = docMgr.read(docId[5]);
+		 rec = page.next();
+		 docMgr.readMetadata(rec.getUri(), mh2);
+		 validateMetadata(mh2);
+		 //Overwriting the existing properties
+		  mh2 = setMetadata();
+		  writeset =docMgr.newWriteSet();
+		  writeset.add(docId[3], mh2,new DOMHandle(getDocumentContent("This is so foo4")));
+		  docMgr.write(writeset);
+		  
+		  page = docMgr.read(docId[3]);
+		  mh2=new DocumentMetadataHandle();
+		  rec = page.next();
+		   docMgr.readMetadata(rec.getUri(), mh2);
+		   validateMetadata(mh2);
+		  
+	  }
+	@Test 
+	public void testWriteMultipleBinaryDocWithDefaultMetadata2() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		 BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		 DocumentMetadataHandle mh = setMetadata();
+		 	 
+		 File file1= null,file2=null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileHandle handle1 = new FileHandle(file1);
+		 writeset.add("/1/"+docId[0],handle1.withFormat(Format.BINARY));
+		 
+		 writeset.add("/2/"+docId[0],new DocumentMetadataHandle().withQuality(5),handle1.withFormat(Format.BINARY));
+		 
+		 file2 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[1]);
+		 FileHandle handle2 = new FileHandle(file2);
+		 writeset.add("/1/"+docId[1],new DocumentMetadataHandle().withCollections("collection1"),handle2.withFormat(Format.BINARY));
+		 
+		 writeset.addDefault(mh);
+		 
+		 writeset.add("/2/"+docId[1],handle2.withFormat(Format.BINARY));
+		 docMgr.write(writeset);
+		 
+		
+		 DocumentPage page = docMgr.read("/1/Pandakarlino.jpg");
+		 DocumentRecord rec;   
+		    rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh);
+//		   System.out.println(rec.getUri()+mh.getQuality());
+		     assertEquals("default quality",0,mh.getQuality());
+		    validateDefaultMetadata(mh);
+		  page = docMgr.read("/2/Pandakarlino.jpg");
+		 rec = page.next();
+	     docMgr.readMetadata(rec.getUri(), mh);
+		 assertEquals(" quality",5,mh.getQuality());
+		 
+		 assertTrue("default collections reset",mh.getCollections().isEmpty());
+	 
+	     page = docMgr.read("/1/mlfavicon.png");
+	     rec = page.next();
+		 docMgr.readMetadata(rec.getUri(), mh);
+		 assertEquals("default quality",0,mh.getQuality());
+//		 System.out.println(rec.getUri()+mh.getCollections().isEmpty());
+		 assertFalse("default collections reset",mh.getCollections().isEmpty());
+	 
+	   page = docMgr.read("/2/mlfavicon.png");
+	     rec = page.next();
+		 docMgr.readMetadata(rec.getUri(), mh);
+		 validateMetadata(mh);
+}
+
+	/*
+	 * This is test is made up for the github issue 25
+	 */
+@Test
+	public void testWriteMultipleJSONDocsWithDefaultMetadata2() throws Exception  
+	  {
+		// Synthesize input content
+        StringHandle doc1 = new StringHandle(
+                "{\"number\": 1}").withFormat(Format.JSON);
+        StringHandle doc2 = new StringHandle(
+                "{\"number\": 2}").withFormat(Format.JSON);
+        StringHandle doc3 = new StringHandle(
+                "{\"number\": 3}").withFormat(Format.JSON);
+        StringHandle doc4 = new StringHandle(
+                "{\"number\": 4}").withFormat(Format.JSON);
+        StringHandle doc5 = new StringHandle(
+                "{\"number\": 5}").withFormat(Format.JSON);
+
+        // Synthesize input metadata
+        DocumentMetadataHandle defaultMetadata1 = 
+                new DocumentMetadataHandle().withQuality(1);
+        DocumentMetadataHandle defaultMetadata2 = 
+                new DocumentMetadataHandle().withQuality(2);
+        DocumentMetadataHandle docSpecificMetadata = 
+                new DocumentMetadataHandle().withCollections("mySpecificCollection");
+
+        // Create and build up the batch
+        JSONDocumentManager jdm = client.newJSONDocumentManager();
+        DocumentWriteSet batch = jdm.newWriteSet();
+
+        // use system default metadata
+        batch.add("doc1.json", doc1);       // system default metadata
+
+        // using batch default metadata
+        batch.addDefault(defaultMetadata1);  
+        batch.add("doc2.json", doc2);       // batch default metadata
+        batch.add("doc3.json", docSpecificMetadata, doc3);
+        batch.add("doc4.json", doc4);       // batch default metadata
+
+        // replace batch default metadata with new metadata
+        batch.addDefault(defaultMetadata2); 
+        batch.add("doc5.json", doc5);       // batch default 
+
+        // Execute the write operation
+        jdm.write(batch);
+        DocumentPage page ;
+	    DocumentRecord rec;
+        // Check the results
+        // Doc1 should have the system default quality of 0
+        page = jdm.read("doc1.json");
+	    DocumentMetadataHandle mh = new DocumentMetadataHandle();
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    validateDefaultMetadata(mh);
+	    assertEquals("default quality",0,mh.getQuality());
+	        
+	    // Doc2 should use the first batch default metadata, with quality 1
+	    page = jdm.read("doc2.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    System.out.print(mh.getCollections().isEmpty());
+	    assertEquals("default quality",1,mh.getQuality());
+	    assertTrue("default collections reset",mh.getCollections().isEmpty());
+	    
+        // Doc3 should have the system default document quality (0) because quality
+        // was not included in the document-specific metadata. It should be in the
+        // collection "mySpecificCollection", from the document-specific metadata.
+        
+	    page = jdm.read("doc3.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",0,mh.getQuality());
+	    assertEquals("default collection must change","[mySpecificCollection]",mh.getCollections().toString());
+	    
+	    DocumentMetadataHandle doc3Metadata =  
+                jdm.readMetadata("doc3.json", new DocumentMetadataHandle());
+        System.out.println("doc3 quality: Expected=0, Actual=" + doc3Metadata.getPermissions());
+        System.out.print("doc3 collections: Expected: myCollection, Actual=");
+        for (String collection : doc3Metadata.getCollections()) {
+            System.out.print(collection + " ");
+        }
+        System.out.println();
+
+        // Doc 4 should also use the 1st batch default metadata, with quality 1
+        page = jdm.read("doc4.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",1,mh.getQuality());
+	    assertTrue("default collections reset",mh.getCollections().isEmpty());
+	    // Doc5 should use the 2nd batch default metadata, with quality 2
+	    page = jdm.read("doc5.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",2,mh.getQuality());
+	    
+	  }
+	@Test 
+	public void testWriteGenericDocMgrWithDefaultMetadata() throws Exception  
+	  {
+		 String docId[] = {"Sega-4MB.jpg"};
+		  
+		GenericDocumentManager docMgr = client.newDocumentManager();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		 DocumentMetadataHandle mh = setMetadata();
+		    
+		 writeset.addDefault(mh); // Adding default metadata to the entire batch
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileInputStream fis = new FileInputStream(file1);
+		 InputStreamHandle handle1 = new InputStreamHandle(fis);
+		 handle1.setFormat(Format.BINARY);
+		 
+		 writeset.add("/generic/Pandakarlino.jpg",handle1); // This document implicitly gets the default metadata that we added in the begining
+		 
+	     JacksonHandle jh = new JacksonHandle();
+	     ObjectMapper objM = new ObjectMapper();
+	     JsonNode jn = objM.readTree(new String("{\"animal\":\"dog\", \"says\":\"woof\"}"));
+	     jh.set(jn);
+	     jh.setFormat(Format.JSON);
+	     
+	     writeset.add("/generic/dog.json",new DocumentMetadataHandle().withQuality(10),jh); //This document suppose to get the in scope metadata quality and should set collections to system default
+	     
+	     String foo1 = "This is foo1 of byte Array";
+	     byte[] ba = foo1.getBytes();
+	     BytesHandle bh = new BytesHandle(ba);
+	     bh.setFormat(Format.TEXT);
+	     
+	     writeset.add("/generic/foo1.txt",bh);
+	     
+	     DOMSource ds = new DOMSource(getDocumentContent("This is so foo1"));
+	     SourceHandle sh = new SourceHandle();
+	     sh.set(ds);
+	     sh.setFormat(Format.XML);
+	     DocumentMetadataHandle mh2 = new DocumentMetadataHandle();
+	     writeset.add("/generic/foo.xml", mh2.withCollections("genericCollection"), sh); //This document should over write the system default and default collection list and get document specific collection
+	     
+		 docMgr.write(writeset);
+	     
+		 DocumentPage page = docMgr.read("/generic/Pandakarlino.jpg","/generic/foo1.txt");
+		  
+		    while(page.hasNext()){
+		    	DocumentRecord rec = page.next();
+		    	docMgr.readMetadata(rec.getUri(), mh);
+		    	System.out.println(rec.getUri());
+		    	validateMetadata(mh);
+		    }
+		    validateMetadata(mh);
+		     page = docMgr.read("/generic/dog.json");
+			 DocumentRecord rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh);
+			 assertEquals("default quality",10,mh.getQuality());
+			 assertTrue("default collections missing",mh.getCollections().isEmpty());
+			 
+			 page = docMgr.read("/generic/foo.xml");
+			 rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh);
+			 assertEquals("default quality",0,mh.getQuality());
+			 assertEquals("default collection must change","[genericCollection]",mh.getCollections().toString());
+		    
+	    }
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadatawithRawXML.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadatawithRawXML.java
new file mode 100644
index 000000000..25248c415
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteMetadatawithRawXML.java
@@ -0,0 +1,500 @@
+/**
+ * 
+ */
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.transform.dom.DOMSource;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.Document;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.JacksonHandle;
+import com.marklogic.client.io.JacksonParserHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+import com.marklogic.client.FailedRequestException;
+/**
+ * @author skottam
+ * This test is test the DocumentWriteSet function 
+ * public DocumentWriteSet add(String uri, DocumentMetadataWriteHandle metadataHandle);
+ * This test intention is to test the system default , request wide,  and document specific update to metadata will overwrite the existing metadata
+ * setup: create a usr1 with system level meta data as default
+ * client make a connection with usr1 to do bulk loading 
+ * load set of documents where default metadata is set with raw xml or json documents 
+ * test disableDefault().
+ * 
+ */
+public class TestBulkWriteMetadatawithRawXML extends  BasicJavaClientREST{
+
+	private static String dbName = "TestBulkWriteDefaultMetadataDB3";
+	private static String [] fNames = {"TestBulkWriteDefaultMetadataDB-3"};
+	private static String restServerName = "TestBulkWriteDefaultMetadata3-RESTServer";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		  System.out.println("In Setup");
+		  setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+		  createRESTUser("app-user", "password","rest-writer","rest-reader"  );
+		  createRESTUserWithPermissions("usr1", "password",getPermissionNode("eval",Capability.READ),getCollectionNode("http://permission-collections/"), "rest-writer","rest-reader" );
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+		System.out.println("In tear down" );
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		deleteRESTUser("app-user");
+		deleteRESTUser("usr1");
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		// create new connection for each test below
+		  client = DatabaseClientFactory.newClient("localhost", restPort, "usr1", "password", Authentication.DIGEST);
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+		System.out.println("Running clear script");	
+    	// release client
+    	client.release();
+	}
+	
+	public DocumentMetadataHandle setMetadata(){
+		  // create and initialize a handle on the metadata
+		DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    metadataHandle.getCollections().addAll("my-collection1","my-collection2");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    return	metadataHandle;
+	}
+	public void validateMetadata(DocumentMetadataHandle mh){
+
+	    // get metadata values
+	    DocumentProperties properties = mh.getProperties();
+	    DocumentPermissions permissions = mh.getPermissions();
+	    DocumentCollections collections = mh.getCollections();
+	    
+	    // Properties
+	   // String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    boolean result = actualProperties.contains("size:5|");
+	    assertTrue("Document properties count", result);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    System.out.println(actualPermissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|my-collection1|my-collection2|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	}
+	public void validateDefaultMetadata(DocumentMetadataHandle mh){
+
+	    // get metadata values
+	  
+	    DocumentPermissions permissions = mh.getPermissions();
+	    DocumentCollections collections = mh.getCollections();
+	    
+	    // Permissions
+	    
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|eval:[READ]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	   	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:1|http://permission-collections/|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+//	    System.out.println(actualPermissions);
+	}
+	@Test  
+	public void testWriteMultipleTextDocWithXMLMetadata() throws Exception
+	  {
+		DocumentMetadataHandle mh1,mh2;
+		 String docId[] = {"/foo/test/myFoo1.txt","/foo/test/myFoo2.txt","/foo/test/myFoo3.txt",
+				 			"/foo/test/myFoo4.txt","/foo/test/myFoo5.txt","/foo/test/myFoo6.txt",
+				 			"/foo/test/myFoo7.txt","/foo/test/myFoo8.txt","/foo/test/myFoo9.txt"};
+	    
+	    TextDocumentManager docMgr = client.newTextDocumentManager();
+	         
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	    // get the original metadata
+	 	Document docMetadata = getXMLMetadata("metadata-original.xml");
+	 		// create handle to write metadata
+	 	DOMHandle writeMetadataHandle = new DOMHandle();
+	 	writeMetadataHandle.set(docMetadata);
+	 	
+	 	writeset.addDefault(writeMetadataHandle);
+	    
+	 	writeset.add(docId[0], new StringHandle().with("This is so foo1"));
+	    writeset.add(docId[1], new StringHandle().with("This is so foo2"));
+	    writeset.add(docId[2], new StringHandle().with("This is so foo3"));
+	    docMgr.write(writeset);
+	   //Default properties for are document set
+	   
+	    DocumentPage page = docMgr.read(docId);
+	    DOMHandle mh= new DOMHandle();
+	    while(page.hasNext()){
+	    	DocumentRecord rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh);
+	    	 Document docReadMetadata = mh.get();
+	    	assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("coll2", "string(//*[local-name()='collection'][2])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='Author'])", docReadMetadata);
+	    }
+	   
+	  
+	    //Adding document specific properties in document set2
+	        	
+	    	writeset =docMgr.newWriteSet();
+		 // put metadata
+		    mh2 = setMetadata();
+		    
+		    writeset.add(docId[3], new StringHandle().with("This is so foo4"));
+		    writeset.add(docId[4],mh2, new StringHandle().with("This is so foo5"));
+		    writeset.add(docId[5],writeMetadataHandle, new StringHandle().with("This is so foo6"));
+		    docMgr.write(writeset);
+		     
+
+		    page = docMgr.read(docId[3]);
+		    DocumentRecord rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh2);
+		    validateDefaultMetadata(mh2);
+		    
+		    page = docMgr.read(docId[4]);
+		    mh2=new DocumentMetadataHandle();
+		    rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh2);
+		    validateMetadata(mh2);
+		    
+		    
+		    page = docMgr.read(docId[5]);
+		    rec = page.next();
+		    docMgr.readMetadata(rec.getUri(), mh);
+	    	Document docReadMetadata = mh.get();
+	    	assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("coll2", "string(//*[local-name()='collection'][2])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='Author'])", docReadMetadata);	 
+			 
+	  }
+	@Test  
+	public void testWriteMultipleXMLDocWithXMLMetadata() throws Exception  
+	  {  
+		// put metadata
+	    
+	    String docId[] = {"/foo/test/Foo1.xml","/foo/test/Foo2.xml","/foo/test/Foo3.xml",
+	    					"/foo/test/Foo4.xml","/foo/test/Foo5.xml","/foo/test/Foo6.xml",
+	    					"/foo/test/Foo7.xml","/foo/test/Foo8.xml","/foo/test/Foo8.xml"};
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	 // get the original metadata
+	 	Document docMetadata = getXMLMetadata("metadata-updated.xml");
+	 	// create handle to write metadata
+	 	DOMHandle writeMetadataHandle = new DOMHandle();
+	 	writeMetadataHandle.set(docMetadata);
+	 	 	
+	 	writeset.addDefault(writeMetadataHandle);
+	    
+	    DocumentDescriptor docdisc = docMgr.newDescriptor("test1");
+	    	    
+	    writeset.add(docdisc, new DOMHandle(getDocumentContent("This is so foo1")));
+	    writeset.add(docId[1], new DOMHandle().with(getDocumentContent("This is so foo2")));
+	    writeset.add(docId[2], new DOMHandle().with(getDocumentContent("This is so foo3")));
+	    
+	    docMgr.write(writeset);
+	    	    
+	    DocumentPage page = docMgr.read(docId);
+	    DocumentRecord rec;
+	    Document docReadMetadata =null;
+	    DOMHandle mh= new DOMHandle();
+	    while(page.hasNext()){
+	    	rec = page.next();
+	    	docMgr.readMetadata(rec.getUri(), mh);
+	    	docReadMetadata = mh.get();
+	    	 assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("coll3", "string(//*[local-name()='collection'][2])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("23", "string(//*[local-name()='quality'])", docReadMetadata);
+	 	    assertXpathEvaluatesTo("Aries", "string(//*[local-name()='Author'])", docReadMetadata);
+	    }
+	    assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+	 
+	    // put metadata
+	    DocumentMetadataHandle mh2 = setMetadata();
+	    writeset =docMgr.newWriteSet();
+	    
+	    writeset.add(docId[3], new DOMHandle(getDocumentContent("This is so foo4")));
+	    writeset.addDefault(mh2);
+	    writeset.add(docId[4],writeMetadataHandle ,new DOMHandle().with(getDocumentContent("This is so foo5")));
+	    writeset.add(docId[5], new DOMHandle().with(getDocumentContent("This is so foo6")));
+	    docMgr.write(writeset);
+	    
+	    page = docMgr.read(docId[3]);
+		mh2=new DocumentMetadataHandle();
+		rec = page.next();
+		docMgr.readMetadata(rec.getUri(), mh2);
+		validateDefaultMetadata(mh2);
+		    
+		page = docMgr.read(docId[4]);
+		rec= page.next();
+		docMgr.readMetadata(rec.getUri(), mh);
+    	docReadMetadata = mh.get();
+    	System.out.println(rec.getUri()+ " "+ docReadMetadata+docId[4]);
+    	 assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+ 	    assertXpathEvaluatesTo("coll3", "string(//*[local-name()='collection'][2])", docReadMetadata);
+ 	    assertXpathEvaluatesTo("23", "string(//*[local-name()='quality'])", docReadMetadata);
+ 	    assertXpathEvaluatesTo("Aries", "string(//*[local-name()='Author'])", docReadMetadata);
+		    
+		 page = docMgr.read(docId[5]);
+		 rec = page.next();
+		 docMgr.readMetadata(rec.getUri(), mh2);
+		 validateMetadata(mh2);
+		
+	  }
+	
+	
+	/*
+	 * This is test is made up for the github issue 41
+	 */
+@Test
+	public void testWriteMultipleJSONDocsWithRawJSONMetadata() throws Exception  
+	  {
+		// Synthesize input content
+        
+	
+		StringHandle doc1 = new StringHandle(
+                "{\"number\": 1}").withFormat(Format.JSON);
+        StringHandle doc2 = new StringHandle(
+                "{\"number\": 2}").withFormat(Format.JSON);
+        StringHandle doc3 = new StringHandle(
+                "{\"number\": 3}").withFormat(Format.JSON);
+        StringHandle doc4 = new StringHandle(
+                "{\"number\": 4}").withFormat(Format.JSON);
+        StringHandle doc5 = new StringHandle(
+                "{\"number\": 5}").withFormat(Format.JSON);
+
+        // Synthesize input metadata
+        
+       ObjectMapper mapper = new ObjectMapper();
+       JacksonHandle defaultMetadata1 = new JacksonHandle();
+       Map p = new HashMap();
+       p.put("myString", "json");
+       p.put("myInt", "9");
+       defaultMetadata1.with(constructJSONPropertiesMetadata(p));
+       
+       JacksonHandle defaultMetadata2 =  new JacksonHandle();
+       JsonNode jn = mapper.readTree("{\"quality\": 20}");
+       defaultMetadata2.set(jn);
+       
+       JacksonHandle docSpecificMetadata =  new JacksonHandle();
+       docSpecificMetadata.set(constructJSONCollectionMetadata("http://Json-Uri-spec-collections/"));
+       	
+        // Create and build up the batch
+        JSONDocumentManager jdm = client.newJSONDocumentManager();
+        DocumentWriteSet batch = jdm.newWriteSet();
+
+        // use system default metadata
+        batch.add("doc1.json", doc1);       // system default metadata
+        // using batch default metadata
+        batch.addDefault(defaultMetadata1);  
+        batch.add("doc2.json", doc2);       // batch default metadata
+        batch.add("doc3.json", docSpecificMetadata, doc3);
+        batch.add("doc4.json", doc4);       // batch default metadata
+
+        // replace batch default metadata with new metadata
+        batch.addDefault(defaultMetadata2); 
+        batch.add("doc5.json", doc5);       // batch default 
+
+        // Execute the write operation
+        jdm.write(batch);
+        DocumentPage page ;
+	    DocumentRecord rec;
+        // Check the results
+        // Doc1 should have the system default quality of 0
+        page = jdm.read("doc1.json");
+	    DocumentMetadataHandle mh = new DocumentMetadataHandle();
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    System.out.print(mh.getQuality());
+	    validateDefaultMetadata(mh);
+	    assertEquals("default quality",0,mh.getQuality());
+	        
+	    // Doc2 should use the first batch default metadata, that has only properties i.e. rest needs to be default to system defaults
+	    page = jdm.read("doc2.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    System.out.print(mh.getCollections().isEmpty());
+	    assertEquals("default quality",0,mh.getQuality());
+	    assertTrue("default collections reset",mh.getCollections().isEmpty());
+	    
+        // Doc3 should have the system default document quality (0) because quality
+        // was not included in the document-specific metadata. It should be in the
+        // collection "mySpecificCollection", from the document-specific metadata.
+        
+	    page = jdm.read("doc3.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",0,mh.getQuality());
+	    assertEquals("default collection must change","[http://Json-Uri-spec-collections/]",mh.getCollections().toString());
+	  
+	    // Doc 4 should also use the 1st batch default metadata, with quality 1
+        page = jdm.read("doc4.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",0,mh.getQuality());
+	    assertTrue("default collections reset",mh.getProperties().containsValue("9"));
+	    // Doc5 should use the 2nd batch default metadata, with quality 2
+	    page = jdm.read("doc5.json");
+	    rec = page.next();
+	    jdm.readMetadata(rec.getUri(), mh);
+	    assertEquals("default quality",20,mh.getQuality());
+	    
+	  }
+/*
+ * Git Issue #24 is tested here
+ * 
+ */
+	@Test 
+	public void testWriteGenericDocMgrWithDefaultMetadata() throws Exception  
+	  {
+		 String docId[] = {"Sega-4MB.jpg"};
+		  
+		GenericDocumentManager docMgr = client.newDocumentManager();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		 // put metadata
+		ObjectMapper mapper = new ObjectMapper();
+	       JacksonHandle mh = new JacksonHandle();
+	       Map p = new HashMap();
+	       p.put("myString", "Generic JSON");
+	       p.put("myInt", "19");
+	       mh.with(constructJSONPropertiesMetadata(p));
+		    
+		 writeset.addDefault(mh); // Adding default metadata to the entire batch
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileInputStream fis = new FileInputStream(file1);
+		 InputStreamHandle handle1 = new InputStreamHandle(fis);
+		 handle1.setFormat(Format.BINARY);
+		 
+		 writeset.add("/generic/Sega.jpg",handle1); // This document implicitly gets the default metadata that we added in the begining
+		 
+	     JacksonHandle jh = new JacksonHandle();
+	     ObjectMapper objM = new ObjectMapper();
+	     JsonNode jn = objM.readTree(new String("{\"animal\":\"dog\", \"says\":\"woof\"}"));
+	     jh.set(jn);
+	     jh.setFormat(Format.JSON);
+	     
+	     writeset.add("/generic/dog.json",new JacksonHandle().with(mapper.readTree("{\"quality\": 10}")),jh); //This document suppose to get the in scope metadata quality and should set collections to system default
+	     writeset.disableDefault();
+	     String foo1 = "This is foo1 of byte Array";
+	     byte[] ba = foo1.getBytes();
+	     BytesHandle bh = new BytesHandle(ba);
+	     bh.setFormat(Format.TEXT);
+	     
+	     writeset.add("/generic/foo1.txt",bh);
+	     
+	     DOMSource ds = new DOMSource(getDocumentContent("This is so foo1"));
+	     SourceHandle sh = new SourceHandle();
+	     sh.set(ds);
+	     sh.setFormat(Format.XML);
+	     DocumentMetadataHandle mh2 = new DocumentMetadataHandle();
+	     writeset.add("/generic/foo.xml", new JacksonHandle().with(constructJSONCollectionMetadata("http://Json-Uri-generic-collections/")), sh); //This document should over write the system default and default collection list and get document specific collection
+	     
+		 docMgr.write(writeset);
+		 DocumentMetadataHandle mh1 = new DocumentMetadataHandle();
+		 DocumentPage page = docMgr.read("/generic/Sega.jpg");
+	     DocumentRecord rec = page.next();
+	     docMgr.readMetadata(rec.getUri(),mh1);
+	     assertEquals("default quality",0,mh1.getQuality());
+		 assertTrue("Properties contains value 19",mh1.getProperties().containsValue("19"));
+	     	
+		 	 page = docMgr.read("/generic/dog.json");
+			 rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh1);
+			 assertEquals("default quality",10,mh1.getQuality());
+			 assertTrue("default collections missing",mh1.getCollections().isEmpty());
+			 
+			 page = docMgr.read("/generic/foo1.txt");
+			 rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh1);
+			// until issue 24 is fixed
+			 //this.validateDefaultMetadata(mh1);
+			 
+			 page = docMgr.read("/generic/foo.xml");
+			 rec = page.next();
+			 docMgr.readMetadata(rec.getUri(), mh1);
+			 assertEquals("default quality",0,mh1.getQuality());
+			 assertEquals("default collection must change","[http://Json-Uri-generic-collections/]",mh1.getCollections().toString());
+		    
+	    }
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteSample1.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteSample1.java
new file mode 100644
index 000000000..f284afd52
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteSample1.java
@@ -0,0 +1,350 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Reader;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.StringReader;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.GenericDocumentManager;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.JAXBHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.JacksonHandle;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.FailedRequestException;
+
+
+
+
+
+import javax.xml.transform.dom.DOMSource;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/*
+ * This test is designed to to test simple bulk writes with different types of Managers and different content type like JSON,text,binary,XMl
+ * 
+ *  TextDocumentManager
+ *  XMLDocumentManager
+ *  BinaryDocumentManager
+ *  JSONDocumentManager
+ *  GenericDocumentManager
+ */
+
+
+
+public class TestBulkWriteSample1 extends BasicJavaClientREST  {
+
+	
+	private static String dbName = "TestBulkWriteSampleDB";
+	private static String [] fNames = {"TestBulkWriteSampleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+    @BeforeClass
+	public static void setUp() throws Exception 
+	{
+	   System.out.println("In setup");
+	   setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+	 
+	   //To enable client side http logging
+	   
+//	   System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "debug");
+//	   System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");   
+//       setupAppServicesConstraint(dbName);	  
+
+	}
+	
+  @Before  public void testSetup() throws Exception
+  {
+	  // create new connection for each test below
+	  client = DatabaseClientFactory.newClient("localhost", restPort, "rest-admin", "x", Authentication.DIGEST);
+  }
+    @After
+    public  void testCleanUp() throws Exception
+    {
+    	System.out.println("Running clear script");	
+    	// release client
+    	client.release();
+
+    	
+    }
+    /*
+     * This is cloned in github with tracking bug #27685 
+     * https://github.com/marklogic/java-client-api/issues/23
+     * 
+     * This test uses StringHandle to load 3 text documents, writes to database using bulk write set.
+     * Verified by reading individual documents
+     */
+	@Test  
+	public void testWriteMultipleTextDoc() 
+	  {
+		
+		 String docId[] = {"/foo/test/myFoo1.txt","/foo/test/myFoo2.txt","/foo/test/myFoo3.txt"};
+	    
+	    TextDocumentManager docMgr = client.newTextDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	    
+	    writeset.add(docId[0], new StringHandle().with("This is so foo1"));
+	    writeset.add(docId[1], new StringHandle().with("This is so foo2"));
+	    writeset.add(docId[2], new StringHandle().with("This is so foo3"));
+	    
+	    docMgr.write(writeset);
+	    
+	    assertEquals("Text document write difference", "This is so foo1", docMgr.read(docId[0], new StringHandle()).get());
+	    assertEquals("Text document write difference", "This is so foo2", docMgr.read(docId[1], new StringHandle()).get());
+	    assertEquals("Text document write difference", "This is so foo3", docMgr.read(docId[2], new StringHandle()).get());
+	  }
+	/*
+	* This test uses DOMHandle to load 3 xml documents, writes to database using bulk write set.
+    * Verified by reading individual documents
+    */
+	@Test  
+	public void testWriteMultipleXMLDoc() throws Exception  
+	  {
+		
+	   
+	    String docId[] = {"/foo/test/Foo1.xml","/foo/test/Foo2.xml","/foo/test/Foo3.xml"};
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	    DocumentWriteSet writeset =docMgr.newWriteSet();
+	       
+	    writeset.add(docId[0], new DOMHandle(getDocumentContent("This is so foo1")));
+	    writeset.add(docId[1], new DOMHandle().with(getDocumentContent("This is so foo2")));
+	    writeset.add(docId[2], new DOMHandle().with(getDocumentContent("This is so foo3")));
+	    
+	    docMgr.write(writeset);
+	    
+	    DOMHandle dh = new DOMHandle();
+	    docMgr.read(docId[0], dh);  
+	    
+	    
+	    assertEquals("xml document write difference", "This is so foo1",dh.get().getChildNodes().item(0).getTextContent());
+	    docMgr.read(docId[1], dh);
+	    assertEquals("xml document write difference", "This is so foo2", dh.get().getChildNodes().item(0).getTextContent());
+	    docMgr.read(docId[2], dh);
+	    assertEquals("xml document write difference", "This is so foo3", dh.get().getChildNodes().item(0).getTextContent());
+	  }
+	/*
+	 * This test uses FileHandle to load 3 binary documents with same URI, writes to database using bulk write set.
+     * Expecting an exception.
+	 */
+	@Test (expected = FailedRequestException.class) 
+	public void testWriteMultipleSameBinaryDoc() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		 BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/"  + docId[0]);
+		 FileHandle handle1 = new FileHandle(file1);
+		 writeset.add("/1/"+docId[0],handle1.withFormat(Format.BINARY));
+		 writeset.add("/1/"+docId[0],handle1.withFormat(Format.BINARY));
+		 		  
+		 docMgr.write(writeset);
+		 		
+	    }
+	/*
+	 * This test uses FileHandle to load 3 binary documents, writes to database using bulk write set.
+     * Verified by reading individual documents
+	 */
+	@Test 
+	public void testWriteMultipleBinaryDoc() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		 BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 File file1= null,file2=null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+		 FileHandle handle1 = new FileHandle(file1);
+		 writeset.add("/1/"+docId[0],handle1.withFormat(Format.BINARY));
+		 writeset.add("/2/"+docId[0],handle1.withFormat(Format.BINARY));
+		 file2 = new File("src/test/java/com/marklogic/javaclient/data/"  + docId[1]);
+		 FileHandle handle2 = new FileHandle(file2);
+		 writeset.add("/1/"+docId[1],handle2.withFormat(Format.BINARY));
+		 writeset.add("/2/"+docId[1],handle2.withFormat(Format.BINARY));
+		  
+		 docMgr.write(writeset);
+		 long fsize1 = file1.length(),fsize2 = file2.length();
+		 
+		 
+		 FileHandle readHandle1 = new FileHandle();
+		 docMgr.read("/1/"+docId[0],readHandle1);
+		 
+		 FileHandle readHandle2 = new FileHandle();
+		 docMgr.read("/1/"+docId[1],readHandle2);
+		 System.out.println(file1.getName()+":"+fsize1+" "+readHandle1.get().getName()+":"+readHandle1.get().length());
+		 System.out.println(file2.getName()+":"+fsize2+" "+readHandle2.get().getName()+":"+readHandle2.get().length());
+		 assertEquals("Size of the  File 1"+docId[0],fsize1,readHandle1.get().length());
+		 assertEquals("Size of the  File 1"+docId[1],fsize2,readHandle2.get().length());
+	    }
+
+/*
+	 * This test uses ReaderHandle to load 3 JSON documents, writes to database using bulk write set.
+     * Verified by reading individual documents
+	
+ */
+	@Test
+	public void testWriteMultipleJSONDocs() throws Exception  
+	  {
+		 String docId[] = {"/a.json","/b.json","/c.json"};
+         String json1 = new String("{\"animal\":\"dog\", \"says\":\"woof\"}");
+         String json2 = new String("{\"animal\":\"cat\", \"says\":\"meow\"}");
+         String json3 =  new String("{\"animal\":\"rat\", \"says\":\"keek\"}");
+ 		 Reader strReader = new StringReader(json1);
+		 JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+		 writeset.add(docId[0],new ReaderHandle(strReader).withFormat(Format.JSON));
+		 writeset.add(docId[1],new ReaderHandle(new StringReader(json2)));
+		 writeset.add(docId[2],new ReaderHandle(new StringReader(json3)));
+		  
+		 docMgr.write(writeset);
+		 
+		 ReaderHandle r1 = new ReaderHandle();
+		 docMgr.read(docId[0],r1);
+		 BufferedReader bfr =  new BufferedReader(r1.get());
+		 assertEquals(json1,bfr.readLine());
+		 docMgr.read(docId[1],r1);
+		 assertEquals("Json File Content"+docId[1],json2,new BufferedReader(r1.get()).readLine());
+		 docMgr.read(docId[2],r1);
+		 assertEquals("Json File Content"+docId[2],json3,new BufferedReader(r1.get()).readLine());
+		 bfr.close();
+	    }
+	@Test
+	public void testWriteMultipleJAXBDocs() throws Exception  
+	  {
+		String docId[] ={"/jaxb/iphone.xml","/jaxb/ipad.xml","/jaxb/ipod.xml"};
+		Product product1 = new Product();
+		product1.setName("iPhone");
+		product1.setIndustry("Hardware");
+		product1.setDescription("Very cool Iphone");
+		Product product2 = new Product();
+		product2.setName("iPad");
+		product2.setIndustry("Hardware");
+		product2.setDescription("Very cool Ipad");
+		Product product3 = new Product();
+		product3.setName("iPod");
+		product3.setIndustry("Hardware");
+		product3.setDescription("Very cool Ipod");
+		JAXBContext context = JAXBContext.newInstance(Product.class);
+		 XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		 DocumentWriteSet writeset =docMgr.newWriteSet();
+//		 JAXBHandle contentHandle = new JAXBHandle(context);
+//		 contentHandle.set(product1);
+		 writeset.add(docId[0],new JAXBHandle(context).with(product1));
+		 writeset.add(docId[1],new JAXBHandle(context).with(product2));
+		 writeset.add(docId[2],new JAXBHandle(context).with(product3));
+		  
+		 docMgr.write(writeset);
+		 
+		  DOMHandle dh = new DOMHandle();
+		  docMgr.read(docId[0], dh);
+		 		  
+		  assertEquals("xml document write difference", "Very cool Iphone",dh.get().getChildNodes().item(0).getChildNodes().item(1).getTextContent());
+		    docMgr.read(docId[1], dh);
+		    assertEquals("xml document write difference", "Very cool Ipad", dh.get().getChildNodes().item(0).getChildNodes().item(1).getTextContent());
+		    docMgr.read(docId[2], dh);
+		    assertEquals("xml document write difference", "Very cool Ipod", dh.get().getChildNodes().item(0).getChildNodes().item(1).getTextContent());
+		   
+	    }
+/*
+ * This test uses GenericManager to load all different document types
+ * This test has a bug logged in github with tracking Issue#33
+ * 
+ */
+	@Test 
+	public void testWriteGenericDocMgr() throws Exception  
+	  {
+		 String docId[] = {"Pandakarlino.jpg","mlfavicon.png"};
+		  
+		GenericDocumentManager docMgr = client.newDocumentManager();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		 
+		 File file1= null;
+		 file1 = new File("src/test/java/com/marklogic/javaclient/data/"  + docId[0]);
+		 FileInputStream fis = new FileInputStream(file1);
+		 InputStreamHandle handle1 = new InputStreamHandle(fis);
+		 handle1.setFormat(Format.BINARY);
+		 
+		 writeset.add("/generic/"+docId[0],handle1);
+		 
+	     JacksonHandle jh = new JacksonHandle();
+	     ObjectMapper objM = new ObjectMapper();
+	     JsonNode jn = objM.readTree(new String("{\"animal\":\"dog\", \"says\":\"woof\"}"));
+	     jh.set(jn);
+	     jh.setFormat(Format.JSON);
+	     
+	     writeset.add("/generic/dog.json",jh);
+	     
+	     String foo1 = "This is foo1 of byte Array";
+	     byte[] ba = foo1.getBytes();
+	     BytesHandle bh = new BytesHandle(ba);
+	     bh.setFormat(Format.TEXT);
+	     
+	     writeset.add("/generic/foo1.txt",bh);
+	     
+	     DOMSource ds = new DOMSource(getDocumentContent("This is so foo1"));
+	     SourceHandle sh = new SourceHandle();
+	     sh.set(ds);
+	     sh.setFormat(Format.XML);
+	    
+	     writeset.add("/generic/foo.xml",sh);
+	     
+		 docMgr.write(writeset);
+	     
+	     FileHandle rh = new FileHandle();
+		 
+	     docMgr.read("/generic/"+docId[0],rh);
+		 assertEquals("Size of the  File /generic/"+docId[0],file1.length(),rh.get().length());		 
+		 System.out.println(rh.get().getName()+":"+rh.get().length()+"\n");
+		 
+		 docMgr.read("/generic/foo.xml",rh);
+	     BufferedReader br=new BufferedReader(new FileReader(rh.get()));
+	     br.readLine();
+		 assertEquals("xml document write difference", "This is so foo1", br.readLine() );
+		 docMgr.read("/generic/foo1.txt",rh);
+		 br.close();
+	     br=new BufferedReader(new FileReader(rh.get()));
+	     assertEquals("txt document write difference", foo1, br.readLine() );
+	     br.close();
+	     docMgr.read("/generic/dog.json",rh);
+	     br=new BufferedReader(new FileReader(rh.get()));
+	     assertEquals("Json document write difference", "{\"animal\":\"dog\", \"says\":\"woof\"}", br.readLine() );
+	     br.close();
+		 fis.close();
+	    }
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+	System.out.println("In tear down" );
+	tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteWithTransactions.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteWithTransactions.java
new file mode 100644
index 000000000..7e48f17d7
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBulkWriteWithTransactions.java
@@ -0,0 +1,437 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.HashMap;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.FailedRequestException;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.document.BinaryDocumentManager;
+import com.marklogic.client.document.DocumentPage;
+import com.marklogic.client.document.DocumentRecord;
+import com.marklogic.client.document.DocumentWriteSet;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+
+public class TestBulkWriteWithTransactions extends BasicJavaClientREST {
+
+	private static final int BATCH_SIZE=100;
+	private static final String DIRECTORY ="/bulkTransacton/";
+	private static String dbName = "TestBulkWriteWithTransactionDB";
+	private static String [] fNames = {"TestBulkWriteWithTransactionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	private static int restPort = 8011;
+	private  DatabaseClient client ;
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		System.out.println("In Setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+		createRESTUser("app-user", "password","rest-writer","rest-reader"  );
+		createRESTUserWithPermissions("usr1", "password",getPermissionNode("eval",Capability.READ),getCollectionNode("http://permission-collections/"), "rest-writer","rest-reader" );
+		
+	}
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+		System.out.println("In tear down" );
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		deleteRESTUser("app-user");
+		deleteRESTUser("usr1");
+	}
+	@Before
+	public void setUp() throws Exception {
+
+		// create new connection for each test below
+		client = DatabaseClientFactory.newClient("localhost", restPort, "usr1", "password", Authentication.DIGEST);
+	}
+	@After
+	public void tearDown() throws Exception {
+		System.out.println("Running clear script");	
+		// release client
+		client.release();
+	}
+	public DocumentMetadataHandle setMetadata(){
+		// create and initialize a handle on the metadata
+		DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+		metadataHandle.getCollections().addAll("my-collection1","my-collection2");
+		metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+		metadataHandle.getProperties().put("reviewed", true);
+		metadataHandle.getProperties().put("myString", "foo");
+		metadataHandle.getProperties().put("myInteger", 10);
+		metadataHandle.getProperties().put("myDecimal", 34.56678);
+		metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+		metadataHandle.setQuality(23);
+		return	metadataHandle;
+	}
+	public void validateMetadata(DocumentMetadataHandle mh){
+
+		// get metadata values
+		DocumentProperties properties = mh.getProperties();
+		DocumentPermissions permissions = mh.getPermissions();
+		DocumentCollections collections = mh.getCollections();
+
+		// Properties
+		// String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+		String actualProperties = getDocumentPropertiesString(properties);
+		boolean result = actualProperties.contains("size:5|");
+//		System.out.println(actualProperties);
+		assertTrue("Document properties count", result);
+
+		// Permissions
+		String expectedPermissions1 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+		String expectedPermissions2 = "size:4|rest-reader:[READ]|eval:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+		String actualPermissions = getDocumentPermissionsString(permissions);
+//		System.out.println(actualPermissions);
+		if(actualPermissions.contains("[UPDATE, READ]"))
+			assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+		else if(actualPermissions.contains("[READ, UPDATE]"))
+			assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+		else
+			assertEquals("Document permissions difference", "wrong", actualPermissions);
+
+		// Collections 
+		String expectedCollections = "size:2|my-collection1|my-collection2|";
+		String actualCollections = getDocumentCollectionsString(collections);
+		assertEquals("Document collections difference", expectedCollections, actualCollections);
+
+	}	
+	public void validateDefaultMetadata(DocumentMetadataHandle mh){
+
+		// get metadata values
+		DocumentPermissions permissions = mh.getPermissions();
+		DocumentCollections collections = mh.getCollections();
+
+		// Permissions
+
+		String expectedPermissions1 = "size:3|rest-reader:[READ]|eval:[READ]|rest-writer:[UPDATE]|";
+		String actualPermissions = getDocumentPermissionsString(permissions);
+		assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+
+		// Collections 
+		String expectedCollections = "size:1|http://permission-collections/|";
+		String actualCollections = getDocumentCollectionsString(collections);
+
+		assertEquals("Document collections difference", expectedCollections, actualCollections);
+		//	    System.out.println(actualPermissions);
+	}
+	public void validateRecord(DocumentRecord record,Format type) {
+
+		assertNotNull("DocumentRecord should never be null", record);
+		assertNotNull("Document uri should never be null", record.getUri());
+		assertTrue("Document uri should start with " + DIRECTORY, record.getUri().startsWith(DIRECTORY));
+		assertEquals("All records are expected to be in same format", type, record.getFormat());
+	}
+/*
+This is a basic test with transaction, and doing commit
+*/
+	@Test
+public void testBulkWritewithTransactionCommit() throws Exception {
+
+		int count=1;
+		Transaction t= client.openTransaction();
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		HashMap map= new HashMap();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		for(int i =0;i<102;i++){
+			writeset.add(DIRECTORY+"first"+i+".xml", new DOMHandle(getDocumentContent("This is so first"+i)));
+			map.put(DIRECTORY+"first"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is so first"+i)));
+			if(count%BATCH_SIZE == 0){
+				docMgr.write(writeset,t);
+				writeset = docMgr.newWriteSet();
+			}
+			count++;
+		}
+		if(count%BATCH_SIZE > 0){
+			docMgr.write(writeset,t);
+		}
+		String uris[] = new String[102];
+		for(int i =0;i<102;i++){
+			uris[i]=DIRECTORY+"first"+i+".xml";
+		}
+		try{t.commit();
+		count=0;
+		DocumentPage page = docMgr.read(uris);
+		DOMHandle dh = new DOMHandle();
+		while(page.hasNext()){
+			DocumentRecord rec = page.next();
+			validateRecord(rec,Format.XML);
+			rec.getContent(dh);
+			assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+			count++;
+		}
+		}catch(Exception e)
+		{System.out.println(e.getMessage());throw e;}
+		assertEquals("document count", 102,count); 
+
+	}
+	/*
+	 * This test is trying to bulk insert documents with transaction open and not commited and try to read documents before commit.
+	 */
+@Test
+public void testBulkWritewithTransactionsNoCommit() throws Exception {
+		int count=1;boolean tstatus =true;
+		Transaction t1 = client.openTransaction();
+		try{ 
+			XMLDocumentManager docMgr = client.newXMLDocumentManager();
+			HashMap map= new HashMap();
+			DocumentWriteSet writeset =docMgr.newWriteSet();
+			for(int i =0;i<102;i++){
+				writeset.add(DIRECTORY+"bar"+i+".xml", new DOMHandle(getDocumentContent("This is so foo"+i)));
+				map.put(DIRECTORY+"bar"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is so foo"+i)));
+				if(count%BATCH_SIZE == 0){
+					docMgr.write(writeset,t1);
+					writeset = docMgr.newWriteSet();
+				}
+				count++;
+			}
+			if(count%BATCH_SIZE > 0){
+				docMgr.write(writeset,t1);
+			}
+			String uris[] = new String[102];
+			for(int i =0;i<102;i++){
+				uris[i]=DIRECTORY+"bar"+i+".xml";
+			}
+
+			count=0;
+			DocumentPage page = docMgr.read(t1,uris);
+			DOMHandle dh = new DOMHandle();
+			while(page.hasNext()){
+				DocumentRecord rec = page.next();
+				validateRecord(rec,Format.XML);
+				rec.getContent(dh);
+				assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+				count++;
+			}
+
+			assertEquals("document count", 102,count);
+			t1.rollback();
+			tstatus=false;
+			count=0;
+			page = docMgr.read(uris);
+			dh = new DOMHandle();
+			while(page.hasNext()){
+				DocumentRecord rec = page.next();
+				validateRecord(rec,Format.XML);
+				rec.getContent(dh);
+				assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+				count++;
+			}
+
+			assertEquals("document count", 0,count);
+		
+		}catch(Exception e){
+			System.out.println(e.getMessage());
+			tstatus=true;
+			throw e;
+		}
+		finally{
+			if(tstatus) {t1.rollback();}
+		}
+	}
+//This test is trying load some documents, open a transaction, update only metadata,rollback transacton to see metadata info is not commited 
+@Test public void testBulkWritewithMetadataTransactionNoCommit() throws Exception {
+
+		int count=1;
+		boolean tstatus =true;
+		Transaction t1 = client.openTransaction();
+		try{ 
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		HashMap map= new HashMap();
+		DocumentWriteSet writeset =docMgr.newWriteSet();
+		for(int i =0;i<102;i++){
+			writeset.add(DIRECTORY+"sec"+i+".xml", new DOMHandle(getDocumentContent("This is so sec"+i)));
+			map.put(DIRECTORY+"sec"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is so sec"+i)));
+			if(count%BATCH_SIZE == 0){
+				docMgr.write(writeset);
+				writeset = docMgr.newWriteSet();
+			}
+			count++;
+		}
+		if(count%BATCH_SIZE > 0){
+			docMgr.write(writeset);
+		}
+		count=1;
+		HashMap map2= new HashMap();
+		DocumentMetadataHandle mh = setMetadata();
+		for(int i =0;i<102;i++){
+			writeset.add(DIRECTORY+"sec"+i+".xml",mh, new DOMHandle(getDocumentContent("This is with metadata"+i)));
+			map2.put(DIRECTORY+"sec"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is with metadata"+i)));
+			if(count%BATCH_SIZE == 0){
+				docMgr.write(writeset,t1);
+				writeset = docMgr.newWriteSet();
+			}
+			count++;
+		}
+		if(count%BATCH_SIZE > 0){
+			docMgr.write(writeset,t1);
+		}
+		String uris[] = new String[102];
+		for(int i =0;i<102;i++){
+			uris[i]=DIRECTORY+"sec"+i+".xml";
+		}
+		count=0;
+		DocumentPage page = docMgr.read(t1,uris);
+		DOMHandle dh = new DOMHandle();
+		DocumentMetadataHandle mh2 = new DocumentMetadataHandle();
+		while(page.hasNext()){
+			DocumentRecord rec = page.next();
+			validateRecord(rec,Format.XML);
+			rec.getContent(dh);
+			assertEquals("Comparing the content :",map2.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+			docMgr.readMetadata(rec.getUri(), mh2,t1);
+		    validateMetadata(mh2);
+			count++;
+		}
+		assertEquals("document count", 102,count); 
+		t1.rollback();
+		tstatus=false;
+		count=0;
+		page = docMgr.read(uris);
+		dh = new DOMHandle();
+		mh2 = new DocumentMetadataHandle();
+		while(page.hasNext()){
+			DocumentRecord rec = page.next();
+			validateRecord(rec,Format.XML);
+			rec.getContent(dh);
+			assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+			docMgr.readMetadata(rec.getUri(), mh2);
+		    validateDefaultMetadata(mh2);
+			count++;
+		}
+		assertEquals("document count", 102,count); 
+		
+		}catch(Exception e){
+			System.out.println(e.getMessage());
+			tstatus=true;
+			throw e;
+		}finally{
+			if(tstatus){
+				t1.rollback();
+			}
+		}
+	
+	}
+
+@Test public void testBulkWritewithMetadataTransactioninDiffClientConnection() throws Exception {
+
+	int count=1;
+	boolean tstatus =true;
+	DatabaseClient c = DatabaseClientFactory.newClient("localhost", restPort, "app-user", "password", Authentication.DIGEST);
+	Transaction t1 = client.openTransaction();
+	try{ 
+	XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	HashMap map= new HashMap();
+	DocumentWriteSet writeset =docMgr.newWriteSet();
+	DocumentMetadataHandle mh = setMetadata();
+	for(int i =0;i<102;i++){
+		writeset.add(DIRECTORY+"third"+i+".xml",mh, new DOMHandle(getDocumentContent("This is third"+i)));
+		map.put(DIRECTORY+"third"+i+".xml", convertXMLDocumentToString(getDocumentContent("This is third"+i)));
+		if(count%BATCH_SIZE == 0){
+			docMgr.write(writeset,t1);
+			writeset = docMgr.newWriteSet();
+		}
+		count++;
+	}
+	if(count%BATCH_SIZE > 0){
+		docMgr.write(writeset,t1);
+	}
+	String uris[] = new String[102];
+	for(int i =0;i<102;i++){
+		uris[i]=DIRECTORY+"third"+i+".xml";
+	}
+	count=0;
+	XMLDocumentManager dMgr = c.newXMLDocumentManager();
+	DocumentPage page = dMgr.read(t1,uris);
+	DOMHandle dh = new DOMHandle();
+	DocumentMetadataHandle mh2 = new DocumentMetadataHandle();
+	while(page.hasNext()){
+		DocumentRecord rec = page.next();
+		validateRecord(rec,Format.XML);
+		rec.getContent(dh);
+		assertEquals("Comparing the content :",map.get(rec.getUri()),convertXMLDocumentToString(dh.get()));
+		dMgr.readMetadata(rec.getUri(), mh2,t1);
+	    validateMetadata(mh2);
+		count++;
+	}
+	assertEquals("document count", 102,count); 
+	t1.commit();
+	tstatus=false;
+	
+	}catch(Exception e){
+		System.out.println(e.getMessage());
+		tstatus=true;
+		throw e;
+	}finally{
+		if(tstatus){
+			t1.rollback();
+		}
+		c.release();
+	}
+
+}
+
+@Test (expected = FailedRequestException.class)
+public void testBulkWritewithTransactionCommitTimeOut() throws Exception {
+
+	int count=1;
+	String docId[] = {"Sega-4MB.jpg"};
+	//	boolean tstatus =false;
+	Transaction t= client.openTransaction("timeoutTrans",3);
+	BinaryDocumentManager docMgr = client.newBinaryDocumentManager();
+
+	DocumentWriteSet writeset =docMgr.newWriteSet();
+	File file1= null;
+	file1 = new File("src/test/java/com/marklogic/javaclient/data/" + docId[0]);
+	FileHandle h1 = new FileHandle(file1);
+	for(int i =0;i<102;i++){
+		writeset.add(DIRECTORY+"binary"+i+".jpg", h1);
+		if(count%BATCH_SIZE == 0){
+			docMgr.write(writeset,t);
+			writeset = docMgr.newWriteSet();
+		}
+		count++;
+	}
+	if(count%BATCH_SIZE > 0){
+		docMgr.write(writeset,t);
+	}
+	t.commit();
+	String uris[] = new String[102];
+	for(int i =0;i<102;i++){
+		uris[i]=DIRECTORY+"binary"+i+".jpg";
+	}
+	count=0;
+	FileHandle rh = new FileHandle();
+	DocumentPage page = docMgr.read(uris);
+	while(page.hasNext()){
+		DocumentRecord rec = page.next();
+		validateRecord(rec,Format.BINARY);
+		rec.getContent(rh);
+		assertEquals("Content length :",file1.length(),rh.get().length());
+		count++;
+	}
+	assertEquals("document count", 102,count); 
+
+	
+
+}
+
+
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestBytesHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestBytesHandle.java
new file mode 100644
index 000000000..428ee0dc4
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestBytesHandle.java
@@ -0,0 +1,289 @@
+package com.marklogic.javaclient;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.XMLUnit;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import org.junit.*;
+public class TestBytesHandle extends BasicJavaClientREST{
+
+
+private static String dbName = "BytesHandleDB";
+private static String [] fNames = {"BytesHandleDB-1"};
+private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+public static void setUp() throws Exception{
+	System.out.println("In setup");
+	setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+@SuppressWarnings("null")
+@Test
+public void testXmlCRUD() throws IOException , SAXException, ParserConfigurationException{
+
+	String filename = "xml-original-test.xml";
+	String uri = "/write-xml-domhandle/";
+	System.out.println("Running testXmlCRUD");
+	XMLUnit.setIgnoreWhitespace(true);
+	XMLUnit.setNormalizeWhitespace(true);
+	
+	// connect the client
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x",Authentication.DIGEST);
+	
+	// write docs
+	writeDocumentUsingBytesHandle(client, filename, uri, null,"XML");//***********
+	
+	//read docs
+	BytesHandle contentHandle = readDocumentUsingBytesHandle(client, uri + filename,"XML");
+	
+	// get the contents
+	
+	byte[] readDoc1 = (byte[])contentHandle.get();
+	String readDoc2 = new String(readDoc1);
+	Document readDoc = convertStringToXMLDocument(readDoc2);
+
+	// get xml document for expected result
+	Document expectedDoc = expectedXMLDocument(filename);
+	assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+	
+	// Update the Doc
+		//acquire the content for update
+	String updateFilename = "xml-updated-test.xml";
+	updateDocumentUsingByteHandle(client, updateFilename, uri + filename, "XML");	
+
+		// read the document
+	BytesHandle updateHandle = readDocumentUsingBytesHandle(client, uri+filename, "XML");
+	byte[] readDocUpdateInBytes = updateHandle.get();
+	String readDocUpdateInString= new String(readDocUpdateInBytes);
+
+	// convert actual string to xml doc
+	Document readDocUpdate = convertStringToXMLDocument(readDocUpdateInString);
+
+     // get xml document for expected result
+	Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+	assertXMLEqual("Write XML Difference", expectedDocUpdate, readDocUpdate);
+	
+		// delete the document
+	deleteDocument(client, uri+filename,"XML");
+		
+		// read the deleted document
+	String exception = "";
+    try
+    {
+    	BytesHandle deleteHandle = readDocumentUsingBytesHandle(client, uri+filename, "XML");
+    } catch (Exception e) { exception = e.toString(); }
+    
+    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-xml-domhandle/xml-original-test.xml";
+    assertEquals("Document is not deleted", expectedException, exception);
+    
+    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "XML"));
+   
+	// release client
+	client.release();
+    
+    }
+
+@SuppressWarnings("deprecation")
+@Test
+public void testTextCRUD() throws IOException, ParserConfigurationException, SAXException{
+	String filename = "text-original.txt";
+	String uri = "/write-text-Byteshandle/";	
+	System.out.println("Runing test TextCRUD");
+	
+	// connect the client
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+	
+	// write docs
+	writeDocumentUsingBytesHandle(client, filename, uri, "Text");
+	
+	//read docs
+	BytesHandle contentHandle = readDocumentUsingBytesHandle(client, uri + filename,"Text");
+	
+	// get the contents
+	byte[] fileRead = (byte[])contentHandle.get();
+	//String readContent = contentHandle.get().toString();
+	String readContent = new String(fileRead);
+	String expectedContent = "hello world, welcome to java API";
+	assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+	
+	//UPDATE the doc
+	// acquire the content for update
+	//String updateFilename = "text-updated.txt";
+	String updateFilename = "text-updated.txt";
+	updateDocumentUsingByteHandle(client, updateFilename, uri+filename, "Text");
+
+	//read the document
+	BytesHandle updateHandle = readDocumentUsingBytesHandle(client, uri+filename, "Text");
+	
+	// get the contents
+	byte[] fileReadUpdate = updateHandle.get();
+	String readContentUpdate = new String(fileReadUpdate);
+	String expectedContentUpdate = "hello world, welcome to java API after new updates";
+	
+	assertEquals("Write Text difference", expectedContentUpdate.trim(), readContentUpdate.toString().trim());
+
+	// delete the document
+    deleteDocument(client, uri + filename, "Text");
+    
+ // read the deleted document
+    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Text"));
+    
+    String exception = "";
+    try
+    {
+    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+    } catch (Exception e) { exception = e.toString(); }
+    
+    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-text-Byteshandle/text-original.txt";
+    assertEquals("Document is not deleted", expectedException, exception);
+    
+	// release client
+	client.release();
+
+}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testJsonCRUD() throws IOException, ParserConfigurationException, SAXException{
+	String filename = "json-original.json";
+	String uri = "/write-json-Byteshandle/";
+	System.out.println("Running testJsonCRUD");
+	
+	ObjectMapper mapper = new ObjectMapper();
+	
+	// connect the client
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+
+	// write docs
+	writeDocumentUsingBytesHandle(client, filename, uri, "JSON");
+	
+	// read docs
+	BytesHandle contentHandle = readDocumentUsingBytesHandle(client, uri + filename,"JSON");
+	
+	// get the contents
+	byte[] fileRead = contentHandle.get();
+	JsonNode readContent = mapper.readTree(fileRead);
+
+	// get  expected contents
+	JsonNode expectedContent = expectedJSONDocument(filename);
+	
+	assertTrue("Write JSON document difference", readContent.equals(expectedContent));
+	
+	// update the doc
+    // acquire the content for update
+	String updateFilename = "json-updated.json";
+	updateDocumentUsingByteHandle(client, updateFilename, uri + filename, "JSON"); 
+	
+	// read the document
+	BytesHandle updateHandle = readDocumentUsingBytesHandle(client, uri+filename, "JSON");
+	
+	// get the contents
+	byte[] fileReadUpdate = updateHandle.get();
+	JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+	
+	// get expected contents
+	JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+	assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));
+
+	// delete the document
+    deleteDocument(client, uri + filename, "JSON");
+
+	// read the deleted document
+    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "JSON"));
+    
+    String exception = "";
+    try
+    {
+    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+    } catch (Exception e) { exception = e.toString(); }
+    
+    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-json-Byteshandle/json-original.json";
+    assertEquals("Document is not deleted", expectedException, exception);
+   
+	// release client
+	client.release();
+}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testBinaryCRUD() throws IOException, ParserConfigurationException, SAXException{
+	String filename = "Pandakarlino.jpg";
+	String uri = "/write-bin-Bytehandle/";
+	System.out.println("Running testBinaryCRUD");
+
+	// connect the client
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+	
+	// write docs
+	writeDocumentUsingBytesHandle(client, filename, uri, "Binary");
+	
+	// read docs
+	BytesHandle contentHandle = readDocumentUsingBytesHandle(client, uri + filename,"Binary");
+	
+	// get the contents
+	byte[] fileRead = contentHandle.get();
+	
+	// get the binary size
+	long size = getBinarySizeFromByte(fileRead);
+	long expectedSize = 17154;
+	
+	assertEquals("Binary size difference", expectedSize, size);
+
+	// update the doc
+    // acquire the content for update
+    String updateFilename = "mlfavicon.png";
+    updateDocumentUsingByteHandle(client, updateFilename, uri + filename, "Binary");
+    
+    // read the document 
+    BytesHandle updateHandle = readDocumentUsingBytesHandle(client, uri+filename, "Binary");
+	 
+    // get the contents
+    byte[] fileReadUpdate = updateHandle.get();
+    
+    // get the binary size
+	long sizeUpdate = getBinarySizeFromByte(fileReadUpdate);
+	long expectedSizeUpdate = 3290;
+	//long expectedSizeUpdate = 3322;
+	assertEquals("Binary size difference", expectedSizeUpdate, sizeUpdate);
+	
+	// delete the document
+    deleteDocument(client, uri + filename, "Binary");
+
+	// read the deleted document
+    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Binary"));
+    
+    String exception = "";
+    try
+    {
+    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");
+    } catch (Exception e) { exception = e.toString(); }
+    
+    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-bin-Bytehandle/Pandakarlino.jpg";
+    assertEquals("Document is not deleted", expectedException, exception);
+
+    // release client
+	client.release();
+	
+	
+}
+@AfterClass
+public static void tearDown() throws Exception
+{
+	System.out.println("In tear down");
+	tearDownJavaRESTServer(dbName, fNames, restServerName);
+	
+}
+
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestCRUDModulesDb.java b/test-complete/src/test/java/com/marklogic/javaclient/TestCRUDModulesDb.java
new file mode 100644
index 000000000..5a65b0c98
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestCRUDModulesDb.java
@@ -0,0 +1,364 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.ResourceNotFoundException;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ExtensionLibrariesManager;
+import com.marklogic.client.admin.ExtensionLibraryDescriptor;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.DatabaseClient;
+import org.junit.*;
+public class TestCRUDModulesDb extends BasicJavaClientREST {
+
+	private static String dbName = "Modules";
+	private static String [] fNames = {"Modules"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	System.out.println("In setup");
+	assocRESTServer(restServerName, dbName,8011);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testXQueryModuleCRUDDuplicateFile()
+	{	
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		//ExtensionLibrariesManager libsMgr = Common.client.newServerConfigManager().newExtensionLibrariesManager();
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+
+		String Path = "/ext/my/path/to/my/module.xqy";
+		
+		// write XQuery file to the modules database
+		libsMgr.write(Path, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT));
+
+		// read it back
+		String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString.startsWith("xquery version \"1.0-ml\";"));
+		
+		// write Duplicate XQuery file to the modules database with different content
+		libsMgr.write(Path, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT));
+		
+		// read it back to check overwritten
+		String xqueryModuleAsDuplicateString = libsMgr.read(Path, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsDuplicateString.startsWith("xquery version \"1.0-ml\";"));
+		
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+			assertEquals(descriptor.getPath(), Path);
+		}
+
+		// delete it
+		libsMgr.delete(Path);
+		
+		try {
+			// read deleted module
+			xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			// pass;
+		}
+	
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testXQueryModuleCRUDDifferentPath() {
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		String firstPath = "/ext/my/path/to/my/module.xqy";
+		String secondPath = "/ext/my/path/to/my/other/module.xqy" ;
+		// write XQuery file to the modules database
+		libsMgr.write(firstPath, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT));
+		
+		// write XQuery file to the modules database Different Path 
+		libsMgr.write(secondPath, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT));
+		
+		// read 1st file back
+		String xqueryModuleAsString = libsMgr.read(firstPath, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString.startsWith("xquery version \"1.0-ml\";"));
+		
+		// read 2nd file back
+		String xqueryModuleAsString1 = libsMgr.read(secondPath, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString1.startsWith("xquery version \"1.0-ml\";"));
+		
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();
+		assertEquals("number of modules installed", descriptors.length, 2);
+		assertEquals(descriptors[0].getPath(), firstPath );
+		assertEquals(descriptors[1].getPath(), secondPath);
+		
+		// delete it
+		libsMgr.delete(firstPath );
+		libsMgr.delete(secondPath);
+		
+		try {
+			// read deleted module
+			xqueryModuleAsString = libsMgr.read(firstPath, new StringHandle()).get();
+			xqueryModuleAsString = libsMgr.read(secondPath, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			// pass;
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testXQueryModuleCRUDBinaryFile() {
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		
+		String Path = "/ext/my/path/to/my/module.xqy";
+		
+		// write XQuery file to the modules database
+		libsMgr.write(Path, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/binary.jpg")).withFormat(Format.BINARY));
+
+		// read it back
+			FileHandle f = new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/binary.jpg"));
+		assertEquals(f.getByteLength(),libsMgr.read(Path, new StringHandle()).getByteLength());
+		
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+			assertEquals(descriptor.getPath(), Path);
+		}
+
+		// delete it
+		libsMgr.delete(Path);
+		
+		try {
+			// read deleted module
+		String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			// pass;
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testXQueryModuleCRUDTextFile() {
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		
+		String Path = "/ext/my/path/to/my/module.xqy";
+		
+		// write XQuery file to the modules database
+		libsMgr.write(Path, new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/readme.txt")).withFormat(Format.TEXT));
+
+		// read it back
+		String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString.startsWith("Copyright 2012 MarkLogic Corporation"));
+		
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+			assertEquals(descriptor.getPath(), Path);
+		}
+
+		// delete it
+		libsMgr.delete(Path);
+
+		try {
+			// read deleted module
+		 xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			// pass;
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testXQueryModuleCRUDXmlFile() {
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		
+		String Path = "/ext/my/path/to/my/module.xqy";
+		FileHandle f = new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/all_well.xml")).withFormat(Format.XML);
+
+		// write XQuery file to the modules database
+		libsMgr.write(Path, f);
+
+		// read it back
+		assertEquals(f.getByteLength(), libsMgr.read(Path, new StringHandle()).getByteLength());
+		
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+		assertEquals(descriptor.getPath(), Path);
+		}
+
+		// delete it
+		libsMgr.delete(Path);
+		
+		try {
+			// read deleted module
+		 String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			// pass;
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testXQueryModuleReadModulesDb() {
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		
+		String Path = "/ext/my/path/to/my/module.xqy";
+		FileHandle f = new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT);
+
+		// write XQuery file to the modules database
+		libsMgr.write(Path, f);
+
+		// read it back
+
+		String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString.contains("let $x := (1,2,3,4,5)"));
+			
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();	
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+			assertEquals(descriptor.getPath(), Path);
+			System.out.println("Path returned by Descriptor "+ descriptor.getPath());
+		}
+		System.out.println("Path"+Path);
+		// delete it
+		libsMgr.delete(Path);
+		try {
+			// read deleted module
+		xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			System.out.println("Reading deleted file Failed");
+			// pass;
+		}
+		try{
+			libsMgr.delete(Path);
+		}catch(Exception e){
+			System.out.println("Attempt to Delete Non exsting file Failed");
+			e.printStackTrace();
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testXQueryModuleReadExtensionLibraryDescriptor () {
+		System.out.println("testXQueryModuleReadExtensionLibraryDescriptor");
+		
+DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get a manager
+		ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+		
+		String Path = "/ext/my/path/to/my/module.xqy";
+		FileHandle f = new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/module.xqy")).withFormat(Format.TEXT);
+
+		// write XQuery file to the modules database
+		libsMgr.write(Path, f);
+
+		// read it back
+
+		String xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		assertTrue("module read and read back", xqueryModuleAsString.contains("let $x := (1,2,3,4,5)"));
+			
+		// get the list of descriptors
+		ExtensionLibraryDescriptor[] descriptors = libsMgr.list();	
+		assertEquals("number of modules installed", descriptors.length, 1);
+		
+		for (ExtensionLibraryDescriptor descriptor : descriptors) {
+			descriptor.setPath("/ext/my/path/to/my/new/module.xqy");
+			String xqueryModuleAsStringNew = libsMgr.read(Path, new StringHandle()).get();		
+			System.out.println("Path returned by Descriptor "+ descriptor.getPath()+"Document returned by Descriptor"+xqueryModuleAsStringNew);
+			libsMgr.delete(descriptor.getPath());
+		}
+		
+		// delete it
+		libsMgr.delete(Path);
+
+		try {
+			// read deleted module
+		xqueryModuleAsString = libsMgr.read(Path, new StringHandle()).get();
+		} catch (ResourceNotFoundException e) {
+			System.out.println("Reading deleted file Failed");
+			// pass;
+		}
+		try{
+			libsMgr.delete(Path);
+		}catch(Exception e){
+			System.out.println("Attempt to Delete Non exsting file Failed");
+			e.printStackTrace();
+		}
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+public void testXQueryModuleCRUDXmlFileNegative() {
+	
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+	
+	// get a manager
+	ExtensionLibrariesManager libsMgr = client.newServerConfigManager().newExtensionLibrariesManager();
+	
+	String Path = "/foo/my/path/to/my/module.xqy";
+	FileHandle f = new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/all_well.xml")).withFormat(Format.XML);
+
+	// write XQuery file to the modules database
+	try{
+	libsMgr.write(Path, f);
+	}catch(ResourceNotFoundException e){
+		assertEquals("Negative test Passed as","Local message: Could not write resource at /foo/my/path/to/my/module.xqy. Server Message: /v1/foo/my/path/to/my/module.xqy" , e.getMessage());
+	}
+	// delete it
+	try{
+		libsMgr.delete(Path);
+	}catch(Exception e){
+		assertEquals("", "Local message: Could not delete resource at /foo/my/path/to/my/module.xqy. Server Message: /v1/foo/my/path/to/my/module.xqy", e.getMessage());
+	}
+		
+}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		try{
+			deleteRESTServer(restServerName); 
+		}catch(Exception e){
+			e.printStackTrace(); 
+		}	
+	}
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestConstraintCombination.java b/test-complete/src/test/java/com/marklogic/javaclient/TestConstraintCombination.java
new file mode 100644
index 000000000..7c7b2877a
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestConstraintCombination.java
@@ -0,0 +1,224 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestConstraintCombination extends BasicJavaClientREST {
+
+	private static String dbName = "ConstraintCombinationDB";
+	private static String [] fNames = {"ConstraintCombinationDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  addRangeElementAttributeIndex(dbName, "dateTime", "http://example.com", "entry", "", "date");
+	  addRangeElementIndex(dbName, "int", "http://example.com", "scoville");
+	  addRangeElementIndex(dbName, "decimal", "http://example.com", "rating");
+	  addField(dbName, "bbqtext");
+	  includeElementField(dbName, "bbqtext", "http://example.com", "title");
+	  includeElementField(dbName, "bbqtext", "http://example.com", "abstract");
+	  enableCollectionLexicon(dbName);
+	  enableTrailingWildcardSearches(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testConstraintCombination() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testConstraintCombination");
+		
+		String filename1 = "bbq1.xml";
+		String filename2 = "bbq2.xml";
+		String filename3 = "bbq3.xml";
+		String filename4 = "bbq4.xml";
+		String filename5 = "bbq5.xml";
+		
+		String queryOptionName = "constraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://bbq.com/contributor/AuntSally");
+	    metadataHandle2.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle3.getCollections().addAll("http://bbq.com/contributor/Dubois");
+	    metadataHandle4.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle5.getCollections().addAll("http://bbq.com/contributor/Dorothy");
+	    
+		// write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/combination-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/combination-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/combination-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/combination-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/combination-constraint/", metadataHandle5, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:BBQ AND flavor:smok* AND heat:moderate AND contributor:AuntSally AND (summary:Southern AND summary:classic)");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/combination-constraint/bbq1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='facet']//*[local-name()='facet-value']//@*[local-name()='count'])", resultDoc);
+		assertXpathEvaluatesTo("Moderate (500 - 2500)", "string(//*[local-name()='facet']//*[local-name()='facet-value'])", resultDoc);
+	    
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testConstraintCombinationWordAndCollection() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testConstraintCombinationWordAndCollection");
+		
+		String filename1 = "bbq1.xml";
+		String filename2 = "bbq2.xml";
+		String filename3 = "bbq3.xml";
+		String filename4 = "bbq4.xml";
+		String filename5 = "bbq5.xml";
+		
+		String queryOptionName = "constraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://bbq.com/contributor/AuntSally");
+	    metadataHandle2.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle3.getCollections().addAll("http://bbq.com/contributor/Dubois");
+	    metadataHandle4.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle5.getCollections().addAll("http://bbq.com/contributor/Dorothy");
+	    
+		// write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/combination-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/combination-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/combination-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/combination-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/combination-constraint/", metadataHandle5, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:pigs contributor:BigTex");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/combination-constraint/bbq4.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testConstraintCombinationFieldAndRange() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("testConstraintCombinationFieldAndRange");
+		
+		String filename1 = "bbq1.xml";
+		String filename2 = "bbq2.xml";
+		String filename3 = "bbq3.xml";
+		String filename4 = "bbq4.xml";
+		String filename5 = "bbq5.xml";
+		
+		String queryOptionName = "constraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://bbq.com/contributor/AuntSally");
+	    metadataHandle2.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle3.getCollections().addAll("http://bbq.com/contributor/Dubois");
+	    metadataHandle4.getCollections().addAll("http://bbq.com/contributor/BigTex");
+	    metadataHandle5.getCollections().addAll("http://bbq.com/contributor/Dorothy");
+	    
+		// write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/combination-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/combination-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/combination-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/combination-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/combination-constraint/", metadataHandle5, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("summary:Louisiana AND summary:sweet heat:moderate");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/combination-constraint/bbq3.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDOMHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDOMHandle.java
new file mode 100644
index 000000000..a5d11095b
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDOMHandle.java
@@ -0,0 +1,105 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.*;
+public class TestDOMHandle extends BasicJavaClientREST {
+	
+	
+	private static String dbName = "DOMHandleDB";
+	private static String [] fNames = {"DOMHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-domhandle/";
+		
+		System.out.println("Running testXmlCRUD");
+		
+		XMLUnit.setIgnoreWhitespace(true);
+		XMLUnit.setNormalizeWhitespace(true);
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingDOMHandle(client, filename, uri, "XML");
+				
+		// read docs
+		DOMHandle contentHandle = readDocumentUsingDOMHandle(client, uri + filename, "XML");
+		
+		Document readDoc = contentHandle.get();
+		
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+			    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingDOMHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    DOMHandle updateHandle = readDocumentUsingDOMHandle(client, uri + filename, "XML");
+	 
+	    Document readDocUpdate = updateHandle.get();
+	    
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "XML"));
+	    
+		// release client
+		client.release();
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseAuthentication.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseAuthentication.java
new file mode 100644
index 000000000..053a1659f
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseAuthentication.java
@@ -0,0 +1,107 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+public class TestDatabaseAuthentication extends BasicJavaClientREST{
+	
+	
+	private static String dbName = "DatabaseAuthenticationDB";
+	private static String [] fNames = {"DatabaseAuthenticationDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	private static int restPort=8011;
+	
+	 @BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,restPort);
+	       setupAppServicesConstraint(dbName);	  
+
+	}
+	
+	@Test public void testAuthenticationNone() throws IOException
+	{
+		setAuthentication("application-level");
+		setDefaultUser("rest-admin");
+
+		System.out.println("Running testAuthenticationNone");
+		
+		String filename = "text-original.txt";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011);
+		
+		// write doc
+	    writeDocumentUsingStringHandle(client, filename, "/write-text-doc-app-level/", "Text");
+	 
+	    // read docs
+	 	InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, "/write-text-doc-app-level/" + filename, "Text");
+	 		
+	 	// get the contents
+	 	InputStream fileRead = contentHandle.get();
+	 		
+	 	String readContent = convertInputStreamToString(fileRead);
+	 		
+	 	String expectedContent = "hello world, welcome to java API";
+	 						
+	 	assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+		
+		// release client
+		client.release();
+		
+		setAuthentication("digest");
+		setDefaultUser("nobody");
+	}
+	
+@Test	public void testAuthenticationBasic() throws IOException
+	{
+		setAuthentication("basic");
+		setDefaultUser("rest-writer");
+		
+		System.out.println("Running testAuthenticationBasic");
+		
+		String filename = "text-original.txt";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.BASIC);
+		
+		// write doc
+	    writeDocumentUsingStringHandle(client, filename, "/write-text-doc-basic/", "Text");
+	    
+	    // read docs
+	 	InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, "/write-text-doc-basic/" + filename, "Text");
+	 		
+	 	// get the contents
+	 	InputStream fileRead = contentHandle.get();
+	 		
+	 	String readContent = convertInputStreamToString(fileRead);
+	 		
+	 	String expectedContent = "hello world, welcome to java API";
+	 						
+	 	assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+		
+		// release client
+		client.release();
+		
+		setAuthentication("digest");
+		setDefaultUser("nobody");
+	}
+
+	public void tearDown() throws Exception
+	{
+		System.out.println("In tear down" );
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseClientConnection.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseClientConnection.java
new file mode 100644
index 000000000..1606fec46
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDatabaseClientConnection.java
@@ -0,0 +1,194 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+
+public class TestDatabaseClientConnection extends BasicJavaClientREST{
+	
+	private static String dbName = "DatabaeClientConnectionDB";
+	private static String [] fNames = {"DatabaeClientConnectionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+	
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testReleasedClient() throws IOException
+	{
+		System.out.println("Running testReleasedClient");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write doc
+		writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		
+		// release client
+		client.release();
+		
+		String stringException = "";
+		
+		// write doc on released client
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-txt-doc-released-client/", "Text");
+		} 
+		catch (Exception e) 
+		{
+			stringException = "Client is not available - " + e;
+		}
+		
+		String expectedException = "Client is not available - java.lang.NullPointerException";
+		assertEquals("Exception is not thrown", expectedException, stringException);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testDatabaseClientConnectionExist()
+	{
+		System.out.println("Running testDatabaseClientConnectionExist");
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-reader", "x", Authentication.DIGEST);
+		String[] stringClient = client.toString().split("@");
+		assertEquals("Object does not exist", "com.marklogic.client.impl.DatabaseClientImpl", stringClient[0]);
+		
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testDatabaseClientConnectionInvalidPort() throws IOException
+	{
+		System.out.println("Running testDatabaseClientConnectionInvalidPort");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8033, "rest-reader", "x", Authentication.DIGEST);
+		
+		String expectedException = "com.sun.jersey.api.client.ClientHandlerException: org.apache.http.conn.HttpHostConnectException: Connection to http://localhost:8033 refused";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		assertEquals("Exception is not thrown", expectedException, exception);
+		
+		// release client
+		client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testDatabaseClientConnectionInvalidUser() throws IOException
+	{
+		System.out.println("Running testDatabaseClientConnectionInvalidUser");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "foo-the-bar", "x", Authentication.DIGEST);
+		
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: write failed: Unauthorized. Server Message: Unauthorized";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		//System.out.println(exception);
+		
+	    boolean exceptionIsThrown = exception.contains(expectedException);
+	    assertTrue("Exception is not thrown", exceptionIsThrown);
+		
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testDatabaseClientConnectionInvalidPassword() throws IOException
+	{
+		System.out.println("Running testDatabaseClientConnectionInvalidPassword");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "foobar", Authentication.DIGEST);
+		
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: write failed: Unauthorized. Server Message: Unauthorized";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		//System.out.println(exception);
+		
+		boolean exceptionIsThrown = exception.contains(expectedException);
+	    assertTrue("Exception is not thrown", exceptionIsThrown);
+		
+		// release client
+		client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testDatabaseClientConnectionInvalidHost() throws IOException
+	{
+		System.out.println("Running testDatabaseClientConnectionInvalidHost");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("foobarhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		//String expectedException = "com.sun.jersey.api.client.ClientHandlerException: java.net.UnknownHostException: foobarhost: Name or service not known";
+		String expectedException = "UnknownHostException";
+		
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		System.out.println(exception);
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+		
+		// release client
+		client.release();
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentEncoding.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentEncoding.java
new file mode 100644
index 000000000..3dae8dae9
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentEncoding.java
@@ -0,0 +1,135 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.BytesHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+
+public class TestDocumentEncoding extends BasicJavaClientREST
+{
+	private static String dbName = "DocumentEncodingDB";
+	private static String [] fNames = {"DocumentEncodingDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testEncoding() throws IOException, TransformerException, ParserConfigurationException
+	{
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        DOMImplementation impl = builder.getDOMImplementation();
+
+        Document doc = impl.createDocument(null,null,null);
+        Element e1 = doc.createElement("howto");
+        doc.appendChild(e1);
+        Element e2 = doc.createElement("java");
+        e1.appendChild(e2);
+        e2.setAttribute("url","http://www.rgagnon.com/howto.html");
+        Text text = doc.createTextNode("漢字");
+        e2.appendChild(text);
+
+        // transform the Document into a String
+        DOMSource domSource = new DOMSource(doc);
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Transformer transformer = tf.newTransformer();
+        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+        transformer.setOutputProperty(OutputKeys.ENCODING,"Cp1252");
+        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        java.io.StringWriter sw = new java.io.StringWriter();
+        StreamResult sr = new StreamResult(sw);
+        transformer.transform(domSource, sr);
+        
+        String xml = sw.toString();	
+        System.out.println(xml);
+        
+        XMLDocumentManager docMgr = client.newXMLDocumentManager();
+        StringHandle writeHandle = new StringHandle();
+        writeHandle.set(xml);
+        docMgr.write("/doc/foo.xml", writeHandle);
+        
+        System.out.println(docMgr.read("/doc/foo.xml", new StringHandle()).get());
+        int length1 = docMgr.read("/doc/foo.xml", new BytesHandle()).get().length;
+        System.out.println(length1);
+        
+        // ************************
+        
+        DocumentBuilderFactory factory2 = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder2 = factory2.newDocumentBuilder();
+        DOMImplementation impl2 = builder2.getDOMImplementation();
+
+        Document doc2 = impl2.createDocument(null,null,null);
+        Element x1 = doc2.createElement("howto");
+        doc2.appendChild(x1);
+        Element x2 = doc2.createElement("java");
+        x1.appendChild(x2);
+        x2.setAttribute("url","http://www.rgagnon.com/howto.html");
+        Text text2 = doc2.createTextNode("漢字");
+        x2.appendChild(text2);
+        
+        DOMSource domSource2 = new DOMSource(doc2);
+        TransformerFactory tf2 = TransformerFactory.newInstance();
+        Transformer transformer2 = tf2.newTransformer();
+        transformer2.setOutputProperty(OutputKeys.METHOD, "xml");
+        transformer2.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
+        transformer2.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+        transformer2.setOutputProperty(OutputKeys.INDENT, "yes");
+        java.io.StringWriter sw2 = new java.io.StringWriter();
+        StreamResult sr2 = new StreamResult(sw2);
+        transformer2.transform(domSource2, sr2);
+        String xml2 = sw2.toString();
+        
+        System.out.println("*********** UTF-8 ************");
+        System.out.println(xml2);
+        
+        StringHandle writeHandle2 = new StringHandle();
+        writeHandle2.set(xml2);
+        docMgr.write("/doc/bar.xml", writeHandle2);
+        System.out.println(docMgr.read("/doc/bar.xml", new StringHandle()).get());
+        int length2 = docMgr.read("/doc/bar.xml", new BytesHandle()).get().length;
+        System.out.println(length2);
+        
+        assertEquals("Byte size is not the same", length1, length2);
+        
+        // **************************
+		
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentFormat.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentFormat.java
new file mode 100644
index 000000000..b713a81c0
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentFormat.java
@@ -0,0 +1,679 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import org.junit.*;
+public class TestDocumentFormat extends BasicJavaClientREST {
+	
+	private static String dbName = "TestDocumentFormatDB";
+	private static String [] fNames = {"TestDocumentFormat-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testXMLFormatOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testXMLFormatOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/xml-format-xml-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.XML);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+		
+	    // release the client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testJSONFormatOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testJSONFormatOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/json-format-xml-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.JSON);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		String exception = "";
+		String expectedException = "write failed: Bad Request. Server Message: XDMP-JSONCHAR";
+		
+		try
+		{
+			docMgr.write(docId, handle);
+		} catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+	    // release the client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBinaryFormatOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testBinaryFormatOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/bin-format-xml-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.BINARY);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testTextFormatOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testTextFormatOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/txt-format-xml-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.TEXT);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testJSONFormatOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testJSONFormatOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/json-format-json-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.JSON);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testXMLFormatOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testXMLFormatOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/xml-format-json-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.XML);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testBinaryFormatOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testBinaryFormatOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/bin-format-json-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.BINARY);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testTextFormatOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testTextFormatOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/txt-format-json-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.TEXT);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testBinaryFormatOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testBinaryFormatOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-format-bin-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.BINARY);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testXMLFormatOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testXMLFormatOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/xml-format-bin-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.XML);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		String exception = "";
+		String expectedException = "Local message: write failed: Bad Request. Server Message: XDMP-DOCUTF8SEQ";
+		
+		try
+		{
+			docMgr.write(docId, handle);
+		} catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+	    // release the client
+	    client.release();
+	}	
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testJSONFormatOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testJSONFormatOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/json-format-bin-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.JSON);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		String exception = "";
+		String expectedException = "Local message: write failed: Bad Request. Server Message: XDMP-DOCUTF8SEQ";
+		
+		try
+		{
+			docMgr.write(docId, handle);
+		} catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testTextFormatOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testTextFormatOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-format-bin-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.TEXT);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		String exception = "";
+		String expectedException = "Local message: write failed: Bad Request. Server Message: XDMP-DOCUTF8SEQ";
+		
+		try
+		{
+			docMgr.write(docId, handle);
+		} catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+
+	    // release the client
+	    client.release();
+	}	
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testTextFormatOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testTextFormatOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/txt-format-txt-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.TEXT);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}	
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testXMLFormatOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testXMLFormatOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/xml-format-txt-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.XML);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testJSONFormatOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testJSONFormatOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/json-format-txt-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.JSON);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		String exception = "";
+		String expectedException = "write failed: Bad Request. Server Message: XDMP-JSONCHAR";
+		
+		try
+		{
+			docMgr.write(docId, handle);
+		} catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testBinaryFormatOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testBinaryFormatOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/bin-format-txt-file/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setFormat(Format.BINARY);
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testNegativeJSONFormatWithDOMHandle() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testNegativeJSONFormatWithDOMHandle");
+		
+		String filename = "xml-original.xml";
+		String uri = "/negative-format/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		Document readDoc = expectedXMLDocument(filename);
+		
+		//File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		DOMHandle handle = new DOMHandle();
+		handle.set(readDoc);
+
+		String exception = "";
+		String expectedException = "java.lang.IllegalArgumentException: DOMHandle supports the XML format only";
+		
+		try
+		{
+			handle.setFormat(Format.JSON);
+		} catch (IllegalArgumentException e) { exception = e.toString(); }
+				
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Wrong exception", isExceptionThrown);
+
+	    // release the client
+	    client.release();
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentMimetype.java b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentMimetype.java
new file mode 100644
index 000000000..e71ca8ec4
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestDocumentMimetype.java
@@ -0,0 +1,725 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.io.FileHandle;
+import org.junit.*;
+public class TestDocumentMimetype extends BasicJavaClientREST {
+	
+	private static String dbName = "TestDocumentMimetypeDB";
+	private static String [] fNames = {"TestDocumentMimetypeDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testMatchedMimetypeOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMatchedMimetypeOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/xml-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/xml");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document format
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "XML";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testUnknownMimetypeOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnknownMimetypeOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/xml-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/x-excel");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "XML";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnmatchedMimetypeOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnmatchedMimetypeOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/xml-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("image/svg+xml");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "XML";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnsupportedMimetypeOnXML() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnsupportedMimetypeOnXML");
+		
+		String filename = "flipper.xml";
+		String uri = "/xml-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/vnd.nokia.configuration-message");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "XML";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testMatchedMimetypeOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMatchedMimetypeOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/json-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/json");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document format
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "JSON";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnknownMimetypeOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnknownMimetypeOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/json-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("image/jpeg");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "BINARY";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnmatchedMimetypeOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnmatchedMimetypeOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/json-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("text/html");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "TEXT";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnsupportedMimetypeOnJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnsupportedMimetypeOnJSON");
+		
+		String filename = "json-original.json";
+		String uri = "/json-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/vnd.nokia.configuration-message");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "JSON";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testMatchedMimetypeOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMatchedMimetypeOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("image/jpeg");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document format
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "BINARY";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnknownMimetypeOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnknownMimetypeOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/rtf");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "BINARY";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnmatchedMimetypeOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnmatchedMimetypeOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("text/rtf");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "TEXT";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnsupportedMimetypeOnBinary() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnsupportedMimetypeOnBinary");
+		
+		String filename = "Pandakarlino.jpg";
+		String uri = "/bin-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/vnd.nokia.configuration-message");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "BINARY";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testMatchedMimetypeOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMatchedMimetypeOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/txt-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("text/plain");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document format
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "TEXT";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnknownMimetypeOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnknownMimetypeOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/txt-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/rtf");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "TEXT";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnmatchedMimetypeOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnmatchedMimetypeOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/txt-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("image/jpeg");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "BINARY";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testUnsupportedMimetypeOnText() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testUnsupportedMimetypeOnText");
+		
+		String filename = "text-original.txt";
+		String uri = "/txt-mimetype/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		handle.setMimetype("application/vnd.nokia.configuration-message");
+		
+		// create docId
+		String docId = uri + filename;
+		
+		docMgr.write(docId, handle);
+		
+    	String expectedUri = uri + filename;
+    	String docUri = docMgr.exists(expectedUri).getUri();
+    	assertEquals("URI is not found", expectedUri, docUri);
+    	
+    	// read document mimetype
+    	docMgr.read(docId, handle);
+    	String format = handle.getFormat().name();
+    	String expectedFormat = "TEXT";
+    	
+    	assertEquals("Format does not match", expectedFormat, format);
+		
+	    // release the client
+	    client.release();
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestFieldConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestFieldConstraint.java
new file mode 100644
index 000000000..574eeb97a
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestFieldConstraint.java
@@ -0,0 +1,66 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestFieldConstraint extends BasicJavaClientREST {
+	static String filenames[] = {"bbq1.xml", "bbq2.xml", "bbq3.xml", "bbq4.xml", "bbq5.xml"};
+	static String queryOptionName = "fieldConstraintOpt.xml";
+	private static String dbName = "FieldConstraintDB";
+	private static String [] fNames = {"FieldConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		addField(dbName, "bbqtext");
+		includeElementField(dbName, "bbqtext", "http://example.com", "title");
+		includeElementField(dbName, "bbqtext", "http://example.com", "abstract");
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testFieldConstraint() throws IOException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename:filenames)
+		{
+			writeDocumentReaderHandle(client, filename, "/field-constraint/", "XML");
+		}
+							
+		// write the query options to the database
+		setQueryOption(client, queryOptionName);
+							
+		// run the search
+		SearchHandle resultsHandle = runSearch(client, queryOptionName, "summary:Louisiana AND summary:sweet");
+		
+		// search result
+		String matchResult = "Matched "+resultsHandle.getTotalResults();
+		String expectedMatchResult = "Matched 1";
+		assertEquals("Match results difference", expectedMatchResult, matchResult);
+		
+		String result = returnSearchResult(resultsHandle);
+		String expectedResult = "|Matched 3 locations in /field-constraint/bbq3.xml";
+		
+		assertEquals("Results difference", expectedResult, result);
+						
+		// release client
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestFileHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestFileHandle.java
new file mode 100644
index 000000000..b776dfcb3
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestFileHandle.java
@@ -0,0 +1,318 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestFileHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "FileHandleDB";
+	private static String [] fNames = {"FileHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-filehandle/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingFileHandle(client, filename, uri, "XML");
+				
+		// read docs
+		FileHandle contentHandle = readDocumentUsingFileHandle(client, uri + filename, "XML");
+		
+		// get the contents
+		File fileRead = contentHandle.get();
+		
+		String readContent = convertFileToString(fileRead);
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingFileHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    FileHandle updateHandle = readDocumentUsingFileHandle(client, uri + filename, "XML");
+	 
+	    // get the contents
+	    File fileReadUpdate = updateHandle.get();
+	 	
+	    String readContentUpdate = convertFileToString(fileReadUpdate);
+
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+		// convert actual string to xml doc
+		Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+//	  
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "XML"));
+	    
+		// release client
+		client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testTextCRUD() throws IOException
+	{	
+		String filename = "text-original.txt";
+		String uri = "/write-text-filehandle/";
+		
+		System.out.println("Running testTextCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingFileHandle(client, filename, uri, "Text");
+				
+		// read docs
+		FileHandle contentHandle = readDocumentUsingFileHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		File fileRead = contentHandle.get();
+		
+		String readContent = convertFileToString(fileRead);
+		
+		String expectedContent = "hello world, welcome to java API";
+						
+		assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "text-updated.txt";
+	    updateDocumentUsingFileHandle(client, updateFilename, uri + filename, "Text");
+	    
+	    // read the document
+	    FileHandle updateHandle = readDocumentUsingFileHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		File fileReadUpdate = updateHandle.get();
+		
+		String readContentUpdate = convertFileToString(fileReadUpdate);
+		
+		String expectedContentUpdate = "hello world, welcome to java API after new updates";
+		
+		assertEquals("Write Text difference", expectedContentUpdate.trim(), readContentUpdate.toString().trim());
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "Text");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Text"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "Text");
+	    } catch (Exception e) { exception = e.toString(); }
+//	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testJsonCRUD() throws IOException
+	{	
+		String filename = "json-original.json";
+		String uri = "/write-json-filehandle/";
+		
+		System.out.println("Running testJsonCRUD");
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingFileHandle(client, filename, uri, "JSON");
+				
+		// read docs
+		FileHandle contentHandle = readDocumentUsingFileHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		File fileRead = contentHandle.get();
+		
+		JsonNode readContent = mapper.readTree(fileRead);
+				
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+				
+		assertTrue("Write JSON document difference", readContent.equals(expectedContent));		
+		
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "json-updated.json";
+	    updateDocumentUsingFileHandle(client, updateFilename, uri + filename, "JSON");
+	    
+	    // read the document
+	    FileHandle updateHandle = readDocumentUsingFileHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		File fileReadUpdate = updateHandle.get();
+				
+		JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+		
+		// get expected contents
+		JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+				
+		assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));		
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "JSON");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "JSON"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "JSON");
+	    } catch (Exception e) { exception = e.toString(); }
+
+
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testBinaryCRUD() throws IOException
+	{	
+		String filename = "Pandakarlino.jpg";
+		String uri = "/write-bin-filehandle/";
+		
+		System.out.println("Running testBinaryCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		writeDocumentUsingFileHandle(client, filename, uri, "Binary");
+				
+		// read docs
+		FileHandle contentHandle = readDocumentUsingFileHandle(client, uri + filename, "Binary");
+		
+		// get the contents
+		File fileRead = contentHandle.get();
+		
+		// get the binary size
+		long size = fileRead.length();
+		long expectedSize = 17154;
+		
+		assertEquals("Binary size difference", expectedSize, size);
+		
+		// update the doc
+	    // acquire the content for update
+	    String updateFilename = "mlfavicon.png";
+	    updateDocumentUsingFileHandle(client, updateFilename, uri + filename, "Binary");
+	    
+	    // read the document
+	    FileHandle updateHandle = readDocumentUsingFileHandle(client, uri + filename, "Binary");				
+		
+		// get the contents
+		File fileReadUpdate = updateHandle.get();
+		
+		// get the binary size
+		long sizeUpdate = fileReadUpdate.length();
+		long expectedSizeUpdate = 3322;
+	    
+		assertEquals("Binary size difference", expectedSizeUpdate, sizeUpdate);
+		
+		// delete the document
+	    deleteDocument(client, uri + filename, "Binary");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Binary"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "Binary");
+	    } catch (Exception e) { exception = e.toString(); }
+//	    
+//<<<<<<< .mine
+//	    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent documentServer Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-bin-filehandle/Pandakarlino.jpg";
+//	    assertEquals("Document is not deleted", expectedException, exception);
+//=======
+//	    //String expectedException = "com.marklogic.client.ResourceNotFoundException: Could not read non-existent document";
+//	    //assertEquals("Document is not deleted", expectedException, exception);
+//>>>>>>> .r106786
+
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+	    
+	    // release client
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestInputSourceHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestInputSourceHandle.java
new file mode 100644
index 000000000..4bf2f6a86
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestInputSourceHandle.java
@@ -0,0 +1,129 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.InputSourceHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestInputSourceHandle extends BasicJavaClientREST {
+	
+	
+	private static String dbName = "InputSourceHandleDB";
+	private static String [] fNames = {"InputSourceHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException, TransformerException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-inputsourcehandle/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+				
+		// read docs
+		InputSourceHandle contentHandle = readDocumentUsingInputSourceHandle(client, uri + filename, "XML");
+		
+		// get the contents
+		InputSource fileRead = contentHandle.get();
+		
+		String readContent = convertInputSourceToString(fileRead);
+		System.out.println(readContent);
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    InputSourceHandle updateHandle = readDocumentUsingInputSourceHandle(client, uri + filename, "XML");
+	 
+	    // get the contents
+	    InputSource fileReadUpdate = updateHandle.get();
+	 	
+	    String readContentUpdate = convertInputSourceToString(fileReadUpdate);
+
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+		// convert actual string to xml doc
+		Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+	    
+		// release client
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	
+	}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestInputStreamHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestInputStreamHandle.java
new file mode 100644
index 000000000..a1b741d15
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestInputStreamHandle.java
@@ -0,0 +1,304 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestInputStreamHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "InputStreamHandleDB";
+	private static String [] fNames = {"InputStreamHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-inputstreamhandle/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		
+		String readContent = convertInputStreamToString(fileRead);
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	 
+	    // get the contents
+	    InputStream fileReadUpdate = updateHandle.get();
+	 	
+	    String readContentUpdate = convertInputStreamToString(fileReadUpdate);
+
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+		// convert actual string to xml doc
+		Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+	    
+		// release client
+		client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testTextCRUD() throws IOException
+	{	
+		String filename = "text-original.txt";
+		String uri = "/write-text-inputstreamhandle/";
+		
+		System.out.println("Running testTextCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingInputStreamHandle(client, filename, uri, "Text");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		
+		String readContent = convertInputStreamToString(fileRead);
+		
+		String expectedContent = "hello world, welcome to java API";
+						
+		assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "text-updated.txt";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "Text");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+		
+		String readContentUpdate = convertInputStreamToString(fileReadUpdate);
+		
+		String expectedContentUpdate = "hello world, welcome to java API after new updates";
+		
+		assertEquals("Write Text difference", expectedContentUpdate.trim(), readContentUpdate.toString().trim());
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "Text");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Text"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testJsonCRUD() throws IOException
+	{	
+		String filename = "json-original.json";
+		String uri = "/write-json-inputstreamhandle/";
+		
+		System.out.println("Running testJsonCRUD");
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingInputStreamHandle(client, filename, uri, "JSON");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		JsonNode readContent = mapper.readTree(fileRead);
+		
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+		
+		assertTrue("Write JSON document difference", readContent.equals(expectedContent));
+		
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "json-updated.json";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "JSON");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+
+		JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+		
+		// get expected contents
+		JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+		
+		assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "JSON");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "JSON"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBinaryCRUD() throws IOException
+	{	
+		String filename = "Pandakarlino.jpg";
+		String uri = "/write-bin-inputstreamhandle/";
+		
+		System.out.println("Running testBinaryCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		writeDocumentUsingInputStreamHandle(client, filename, uri, "Binary");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		
+		// get the binary size
+		int size = getBinarySize(fileRead);
+		int expectedSize = 17154;
+		
+		assertEquals("Binary size difference", expectedSize, size);
+		
+		// update the doc
+	    // acquire the content for update
+	    String updateFilename = "mlfavicon.png";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "Binary");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");				
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+		
+		// get the binary size
+		int sizeUpdate = getBinarySize(fileReadUpdate);
+		int expectedSizeUpdate = 3322;
+	    
+		assertEquals("Binary size difference", expectedSizeUpdate, sizeUpdate);
+		
+		// delete the document
+	    deleteDocument(client, uri + filename, "Binary");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Binary"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+			    
+	    // release client
+		client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestKeyValueSearch.java b/test-complete/src/test/java/com/marklogic/javaclient/TestKeyValueSearch.java
new file mode 100644
index 000000000..40a634335
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestKeyValueSearch.java
@@ -0,0 +1,187 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.MatchLocation;
+import com.marklogic.client.query.QueryManager;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.query.KeyValueQueryDefinition;
+import com.marklogic.client.admin.NamespacesManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.SearchHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestKeyValueSearch extends BasicJavaClientREST {
+
+	private static String dbName = "TestKeyValueSearchDB";
+	private static String [] fNames = {"TestKeyValueSearchDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testKeyValueSearch() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testKeyValueSearch");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create transaction
+		Transaction transaction1 = client.openTransaction();
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/key-value-search/", transaction1, "XML");
+		}
+		
+		// commit transaction
+		transaction1.commit();
+		
+		// create transaction
+		Transaction transaction2 = client.openTransaction();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition
+		KeyValueQueryDefinition querydef = queryMgr.newKeyValueDefinition(queryOptionName);
+		querydef.put(queryMgr.newElementLocator(new QName("id")), "0012");
+				
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:element-value-query(fn:QName(\"\", \"id\"), \"0012\", (\"case-sensitive\",\"diacritic-sensitive\",\"punctuation-sensitive\",\"whitespace-sensitive\",\"unstemmed\",\"unwildcarded\",\"lexicon-expand=heuristic\",\"lang=en\"), 1), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testKeyValueSearchWithNS() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testKeyValueSearchWithNS");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		//String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// setup namespaces to test kv with namespaces
+		NamespacesManager nsMgr = client.newServerConfigManager().newNamespacesManager();
+		nsMgr.updatePrefix("dt","http://purl.org/dc/elements/1.1/");
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/key-value-search-ns/", "XML");
+		}
+		
+		//setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition
+		KeyValueQueryDefinition querydef = queryMgr.newKeyValueDefinition();
+		querydef.put(queryMgr.newElementLocator(new QName("dt:date")), "2005-01-01"); 
+				
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		//SearchHandle resultsHandle = new SearchHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/key-value-search-ns/constraint1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testKeyValueSearchJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("testKeyValueSearchJSON");
+		
+		String[] filenames = {"json-original.json", "json-updated.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/key-value-search-json/", "JSON");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition
+		KeyValueQueryDefinition querydef = queryMgr.newKeyValueDefinition();
+		querydef.put(queryMgr.newKeyLocator("firstName"), "Aries");
+			
+		SearchHandle results = queryMgr.search(querydef, new SearchHandle());
+		
+		MatchDocumentSummary[] summaries = results.getMatchResults();
+		
+		for (MatchDocumentSummary summary : summaries) 
+		{
+		    MatchLocation[] locations = summary.getMatchLocations();
+		    for (MatchLocation location : locations) 
+		    {
+		        System.out.println(location.getAllSnippetText());
+		        assertEquals("Invalid value", "Aries", location.getAllSnippetText());
+		    }
+		}
+		
+		// release client
+		client.release();		
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestLinkResultDocuments.java b/test-complete/src/test/java/com/marklogic/javaclient/TestLinkResultDocuments.java
new file mode 100644
index 000000000..363729482
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestLinkResultDocuments.java
@@ -0,0 +1,260 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.XMLStreamReaderHandle;
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import org.junit.*;
+public class TestLinkResultDocuments extends BasicJavaClientREST {
+
+	private static String dbName = "TestLinkResultDocuments";
+	private static String [] fNames = {"TestLinkResultDocuments-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	//  assocXDBCServer(serverName, dbName);
+    //  assocRESTServer(restServerName, dbName);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testMimeType() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running TestLinkResultDocuments");
+		
+		String[] filenames = {"constraint4.xml", "binary.jpg", "constraint4.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			if (filename.contains("xml")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "XML");
+			}
+			else if (filename.contains("json")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "JSON");
+			}
+			else if (filename.contains("jpg")){ 
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "Binary");
+			}
+		}
+		
+		// set query option
+		setQueryOption(client,"LinkResultDocumentsOpt.xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("LinkResultDocumentsOpt.xml");
+		querydef.setCriteria("5");
+	//	QueryOptionsHandle as = new QueryOptionsHandle();
+		
+		// create result handle
+		SearchHandle resultsHandle = queryMgr.search(querydef, new SearchHandle()); 
+		
+		// get the result
+		for (MatchDocumentSummary result : resultsHandle.getMatchResults()) 
+		{
+			System.out.println(result.getMimeType()+ ": Mime Type");
+			System.out.println(result.getPath()+ ": Path");
+			System.out.println(result.getFormat()+ ": Format");
+			System.out.println(result.getUri()+ ": Uri");
+			assertTrue("Uri is Wrong", result.getPath().contains("/mime-type/constraint4.json")||result.getPath().contains("/mime-type/constraint4.xml"));
+		} 
+		
+		
+		XMLStreamReaderHandle shandle = queryMgr.search(querydef, new XMLStreamReaderHandle());
+		String resultDoc2 = shandle.toString();
+		System.out.println("Statics : \n"+resultDoc2);
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testResultDecorator() throws IOException {
+			
+		System.out.println("Running testResultDecorator");
+		
+		String[] filenames = {"constraint4.xml", "binary.jpg", "constraint3.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			if (filename.contains("xml")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "XML");
+			}
+			else if (filename.contains("json")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "JSON");
+			}
+			else if (filename.contains("jpg")){ 
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "Binary");
+			}
+		}
+		try{
+		String OS = System.getProperty("os.name");
+		System.out.println("OS name : "+ OS);
+		File source = null;
+		File target = null;
+		if (OS.contains("Windows 7")){
+			 source = new File("C:/builds/winnt/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+		     target = new File("C:/Program Files/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		else if (OS.contains("Mac OS X")) {
+			source = new File("/space/builder/builds/macosx-64/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+            target = new File("/Users/buildermac/Library/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		else if (OS.contains("Linux")) {
+			source = new File("/space/builder/builds/macosx/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+            target = new File("/opt/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		
+		System.out.println(source.exists());
+	    System.out.println(target.exists());
+	    if (target.exists()){
+	    	target.delete();
+	    }
+	    copyWithChannels(source, target, true);
+		// set query option
+		setQueryOption(client,"LinkResultDocumentsOptDecorator.xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("LinkResultDocumentsOptDecorator.xml");
+		querydef.setCriteria("5");
+		
+		// create result handle
+		SearchHandle resultsHandle = queryMgr.search(querydef, new SearchHandle()); 
+		
+		// get the result
+		for (MatchDocumentSummary result : resultsHandle.getMatchResults()) 
+		{
+			System.out.println(result.getMimeType()+ ": Mime Type");
+			System.out.println(result.getPath()+ ": Path");
+			System.out.println(result.getFormat()+ ": Format");
+			System.out.println(result.getUri()+ ": Uri");
+		}
+		XMLStreamReaderHandle shandle = queryMgr.search(querydef, new XMLStreamReaderHandle());
+		String resultDoc2 = shandle.toString();
+		System.out.println("Statics : \n"+resultDoc2);
+		//libsMgr.delete(Path);
+
+		}
+		catch(Exception e){
+			e.printStackTrace();
+		}
+		// release client
+		
+		client.release();	
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testResultDecoratorNoMimeType() throws IOException {
+		
+		System.out.println("Running testResultDecoratorNoMimeType");
+		
+		String[] filenames = {"constraint4.xml", "binary.jpg", "constraint4.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			if (filename.contains("xml")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "XML");
+			}
+			else if (filename.contains("json")){
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "JSON");
+			}
+			else if (filename.contains("jpg")){ 
+				writeDocumentUsingInputStreamHandle(client, filename, "/mime-type/", "Binary");
+			}
+		}
+		try{	
+		String OS = System.getProperty("os.name");
+		System.out.println("OS name : "+ OS);
+		File source = null;
+		File target = null;
+		if (OS.contains("Windows 7")){
+			 source = new File("C:/builds/winnt/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+		     target = new File("C:/Program Files/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		else if (OS.contains("Mac OS X")) {
+			source = new File("/space/builder/builds/macosx-64/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+            target = new File("/Users/buildermac/Library/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		else if (OS.contains("Linux")) {
+			source = new File("/space/builder/builds/macosx/HEAD/xcc/api_tests/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy");
+            target = new File("/opt/MarkLogic/Modules/MarkLogic/appservices/search/result-decorator-test.xqy");
+		}
+		
+		System.out.println(source.exists());
+	    System.out.println(target.exists());
+	    if (target.exists()){
+	    	target.delete();
+	    }
+	    copyWithChannels(source, target, true);
+		// set query option
+		setQueryOption(client,"LinkResultDocumentsOptDecorator1.xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("LinkResultDocumentsOptDecorator1.xml");
+		querydef.setCriteria("5");
+		
+		// create result handle
+		SearchHandle resultsHandle = queryMgr.search(querydef, new SearchHandle()); 
+		
+		// get the result
+		for (MatchDocumentSummary result : resultsHandle.getMatchResults()) 
+		{
+			System.out.println(result.getMimeType()+ ": Mime Type");
+			System.out.println(result.getPath()+ ": Path");
+			System.out.println(result.getFormat()+ ": Format");
+			System.out.println(result.getUri()+ ": Uri");
+		}
+		XMLStreamReaderHandle shandle = queryMgr.search(querydef, new XMLStreamReaderHandle());
+		String resultDoc2 = shandle.toString();
+		System.out.println("Statics : \n"+resultDoc2);
+		//libsMgr.delete(Path);
+
+		}
+		catch(Exception e){
+			e.printStackTrace();
+		}
+		// release client
+		
+		client.release();	
+		
+	}
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestMetadata.java b/test-complete/src/test/java/com/marklogic/javaclient/TestMetadata.java
new file mode 100644
index 000000000..816425649
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestMetadata.java
@@ -0,0 +1,335 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Calendar;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentCollections;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentPermissions;
+import com.marklogic.client.io.DocumentMetadataHandle.DocumentProperties;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestMetadata extends BasicJavaClientREST{
+	
+	private static String dbName = "TestMetadataDB";
+	private static String [] fNames = {"TestMetadataDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testBinaryMetadataBytesHandle() throws IOException
+	{
+		System.out.println("Running testBinaryMetadataBytesHandle");
+		
+		String filename = "Simple_ScanTe.png";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		   	    
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getCollections().addAll("my-collection");
+	    metadataHandle.getCollections().addAll("another-collection");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    
+	    // write the doc with the metadata
+	    writeDocumentUsingBytesHandle(client, filename, "/write-bin-byteshandle-metadata/", metadataHandle, "Binary");
+	
+	    // create handle to read metadata
+	    DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+	    
+	    // read metadata
+	    readMetadataHandle = readMetadataFromDocument(client, "/write-bin-byteshandle-metadata/" + filename, "Binary");
+	    
+	    // get metadata values
+	    DocumentProperties properties = readMetadataHandle.getProperties();
+	    DocumentPermissions permissions = readMetadataHandle.getPermissions();
+	    DocumentCollections collections = readMetadataHandle.getCollections();
+	    
+	    // Properties
+	    String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    System.out.println("Actual Prop : "+actualProperties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:3|rest-reader:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|another-collection|my-collection|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	    // release the client
+	    client.release();
+	}	
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testTextMetadataStringHandle() throws IOException
+	{
+		System.out.println("Running testTextMetadataStringHandle");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		   	    
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getCollections().addAll("my-collection");
+	    metadataHandle.getCollections().addAll("another-collection");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    
+	    // write the doc with the metadata
+	    writeDocumentUsingStringHandle(client, filename, "/write-text-stringhandle-metadata/", metadataHandle, "Text");
+	
+	    // create handle to read metadata
+	    DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+	    
+	    // read metadata
+	    readMetadataHandle = readMetadataFromDocument(client, "/write-text-stringhandle-metadata/" + filename, "Text");
+	    
+	    // get metadata values
+	    DocumentProperties properties = readMetadataHandle.getProperties();
+	    DocumentPermissions permissions = readMetadataHandle.getPermissions();
+	    DocumentCollections collections = readMetadataHandle.getCollections();
+	    
+	    // Properties
+	    String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:3|rest-reader:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|another-collection|my-collection|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testXMLMetadataJAXBHandle() throws JAXBException
+	{
+		System.out.println("Running testXMLMetadataJAXBHandle");
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		Product product1 = new Product();
+		product1.setName("iPad");
+		product1.setIndustry("Hardware");
+		product1.setDescription("Very cool device");
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getCollections().addAll("my-collection");
+	    metadataHandle.getCollections().addAll("another-collection");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    
+	    // write the doc with the metadata
+	    writeDocumentUsingJAXBHandle(client, product1, "/write-xml-jaxbhandle-metadata/", metadataHandle, "XML");
+	    
+	    // create handle to read metadata
+	    DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+	    
+	    // read metadata
+	    readMetadataHandle = readMetadataFromDocument(client, "/write-xml-jaxbhandle-metadata/" + product1.getName() + ".xml", "XML");
+	    
+	    // get metadata values
+	    DocumentProperties properties = readMetadataHandle.getProperties();
+	    DocumentPermissions permissions = readMetadataHandle.getPermissions();
+	    DocumentCollections collections = readMetadataHandle.getCollections();
+	    
+	    // Properties
+	    String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:3|rest-reader:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|another-collection|my-collection|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testJSONMetadataOutputStreamHandle() throws JAXBException
+	{
+		System.out.println("Running testJSONMetadataOutputStreamHandle");
+		
+		String filename = "myJSONFile.json";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getCollections().addAll("my-collection");
+	    metadataHandle.getCollections().addAll("another-collection");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("myString", "foo");
+	    metadataHandle.getProperties().put("myInteger", 10);
+	    metadataHandle.getProperties().put("myDecimal", 34.56678);
+	    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
+	    metadataHandle.setQuality(23);
+	    
+	    // write the doc with the metadata
+	    writeDocumentUsingOutputStreamHandle(client, filename, "/write-json-outputstreamhandle-metadata/", metadataHandle, "JSON");
+	    
+	    // create handle to read metadata
+	    DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+	    
+	    // read metadata
+	    readMetadataHandle = readMetadataFromDocument(client, "/write-json-outputstreamhandle-metadata/" + filename, "JSON");
+	    
+	    // get metadata values
+	    DocumentProperties properties = readMetadataHandle.getProperties();
+	    DocumentPermissions permissions = readMetadataHandle.getPermissions();
+	    DocumentCollections collections = readMetadataHandle.getCollections();
+	    
+	    // Properties
+	    String expectedProperties = "size:5|reviewed:true|myInteger:10|myDecimal:34.56678|myCalendar:2014|myString:foo|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    
+	    // Permissions
+	    String expectedPermissions1 = "size:3|rest-reader:[READ]|app-user:[UPDATE, READ]|rest-writer:[UPDATE]|";
+	    String expectedPermissions2 = "size:3|rest-reader:[READ]|app-user:[READ, UPDATE]|rest-writer:[UPDATE]|";
+	    String actualPermissions = getDocumentPermissionsString(permissions);
+	    if(actualPermissions.contains("[UPDATE, READ]"))
+	    	assertEquals("Document permissions difference", expectedPermissions1, actualPermissions);
+	    else if(actualPermissions.contains("[READ, UPDATE]"))
+	    	assertEquals("Document permissions difference", expectedPermissions2, actualPermissions);
+	    else
+	    	assertEquals("Document permissions difference", "wrong", actualPermissions);
+	    
+	    // Collections 
+	    String expectedCollections = "size:2|another-collection|my-collection|";
+	    String actualCollections = getDocumentCollectionsString(collections);
+	    assertEquals("Document collections difference", expectedCollections, actualCollections);
+	    
+	    // release the client
+	    client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testJSONMetadataQName() throws JAXBException
+	{
+		System.out.println("Running testJSONMetadataQName");
+		
+		String filename = "myJSONFile.json";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getProperties().put(new QName("http://www.example.com", "foo"), "bar"); 
+	    
+	    // write the doc with the metadata
+	    writeDocumentUsingOutputStreamHandle(client, filename, "/write-json-outputstreamhandle-metadata/", metadataHandle, "JSON");
+	    
+	    // create handle to read metadata
+	    DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+	    
+	    // read metadata
+	    readMetadataHandle = readMetadataFromDocument(client, "/write-json-outputstreamhandle-metadata/" + filename, "JSON");
+	    
+	    // get metadata values
+	    DocumentProperties properties = readMetadataHandle.getProperties();
+	    
+	    // Properties
+	    String expectedProperties = "size:1|{http://www.example.com}foo:bar|";
+	    String actualProperties = getDocumentPropertiesString(properties);
+	    System.out.println(actualProperties);
+	    assertEquals("Document properties difference", expectedProperties, actualProperties);
+	    	    
+	    // release the client
+	    client.release();
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestMetadataXML.java b/test-complete/src/test/java/com/marklogic/javaclient/TestMetadataXML.java
new file mode 100644
index 000000000..776822266
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestMetadataXML.java
@@ -0,0 +1,175 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestMetadataXML extends BasicJavaClientREST {
+	
+	private static String dbName = "TestMetadataXMLDB";
+	private static String [] fNames = {"TestMetadataXMLDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	
+	@Test
+	public void testMetadataXMLCRUD() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMetadataXMLCRUD");
+		
+		String filename = "Simple_ScanTe.png";
+		String uri = "/write-bin-metadata/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+
+		// WRITE
+	    // write the doc
+	    writeDocumentUsingBytesHandle(client, filename, uri, "Binary");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+		String docId = uri + filename;
+	    	    
+	    // write original metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle);
+	    
+	    // create handle to read metadata
+	    DOMHandle readMetadataHandle = new DOMHandle();
+	    
+	    // READ
+	    // read metadata
+	    docMgr.readMetadata(docId, readMetadataHandle);
+	    Document docReadMetadata = readMetadataHandle.get();
+	    	    
+	    assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadata);
+	    assertXpathEvaluatesTo("coll2", "string(//*[local-name()='collection'][2])", docReadMetadata);
+	    assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='Author'])", docReadMetadata);
+	    
+	    // UPDATE
+		// get the update metadata
+		Document docMetadataUpdate = getXMLMetadata("metadata-updated.xml");
+
+		// create handle for metadata update
+		DOMHandle writeMetadataHandleUpdate = new DOMHandle();
+		writeMetadataHandleUpdate.set(docMetadataUpdate);
+		
+		// write updated metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandleUpdate);
+	    
+	    // create handle to read updated metadata
+	    DOMHandle readMetadataHandleUpdate = new DOMHandle();
+
+	    // read updated metadata
+	    docMgr.readMetadata(docId, readMetadataHandleUpdate);
+	    Document docReadMetadataUpdate = readMetadataHandleUpdate.get();
+	    
+	    assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadataUpdate);
+	    assertXpathEvaluatesTo("coll3", "string(//*[local-name()='collection'][2])", docReadMetadataUpdate);
+	    assertXpathEvaluatesTo("23", "string(//*[local-name()='quality'])", docReadMetadataUpdate);
+	    assertXpathEvaluatesTo("Aries", "string(//*[local-name()='Author'])", docReadMetadataUpdate);
+
+	    // DELETE
+	    // write default metadata
+	    docMgr.writeDefaultMetadata(docId);
+
+	    // create handle to read deleted metadata
+	    DOMHandle readMetadataHandleDelete = new DOMHandle();
+	    
+	    // read deleted metadata
+	    docMgr.readMetadata(docId, readMetadataHandleDelete);
+	    Document docReadMetadataDelete = readMetadataHandleDelete.get();
+	    
+	    assertXpathEvaluatesTo("0", "string(//*[local-name()='quality'])", docReadMetadataDelete);
+	    
+	    // release the client
+	    client.release();
+	}	
+
+
+	
+	@Test	
+	public void testMetadataXMLNegative() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testMetadataXMLNegative");
+		
+		String filename = "Simple_ScanTe.png";
+		String uri = "/write-neg-metadata/";
+				
+		// connect the client
+		DatabaseClient client1 = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+	    // write the doc
+	    writeDocumentUsingBytesHandle(client1, filename, uri, "Binary");
+		
+		// connect with another client to write metadata
+		DatabaseClient client2 = DatabaseClientFactory.newClient("localhost", 8011, "rest-reader", "x", Authentication.DIGEST);
+
+		// create doc manager
+		XMLDocumentManager docMgr = client2.newXMLDocumentManager();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+	    String docId = uri + filename;
+	    
+	    String expectedException = "You do not have permission to this method and URL";
+	    String exception = "";
+	    
+	    // write original metadata
+	    try
+	    {
+	    	docMgr.writeMetadata(docId, writeMetadataHandle);
+	    }
+	    catch (Exception e) { exception = e.toString(); } 
+	    
+	    //assertEquals("Could write metadata with forbidden user", expectedException, exception);
+	    
+	    boolean exceptionIsThrown = exception.contains(expectedException);
+	    assertTrue("Exception is not thrown", exceptionIsThrown);
+	    
+	    // release the clients
+	    client1.release();
+	    client2.release();
+	}	
+@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestMultithreading.java b/test-complete/src/test/java/com/marklogic/javaclient/TestMultithreading.java
new file mode 100644
index 000000000..ab1ee3e09
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestMultithreading.java
@@ -0,0 +1,126 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.TextDocumentManager;
+import org.junit.*;
+public class TestMultithreading extends BasicJavaClientREST {
+	
+	private static String dbName = "TestMultithreadingDB";
+	private static String [] fNames = {"TestMultithreadingDBDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testMultithreading() throws InterruptedException
+	{
+		ThreadClass dt1 = new ThreadClass("Thread A");
+        ThreadClass dt2 = new ThreadClass("Thread B");
+
+        dt1.start(); // this will start thread of object 1
+        dt2.start(); // this will start thread of object 2
+        dt2.join();
+        
+        DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-reader", "x", Authentication.DIGEST);
+        TextDocumentManager docMgr = client.newTextDocumentManager();
+        
+        for (int i = 1; i <= 5; i++)
+        {
+        	String expectedUri = "/multithread-content-A/filename" + i + ".txt";
+        	String docUri = docMgr.exists("/multithread-content-A/filename" + i + ".txt").getUri();
+        	assertEquals("URI is not found", expectedUri, docUri);
+        }
+        
+        for (int i = 1; i <= 5; i++)
+        {
+        	String expectedUri = "/multithread-content-B/filename" + i + ".txt";
+        	String docUri = docMgr.exists("/multithread-content-B/filename" + i + ".txt").getUri();
+        	assertEquals("URI is not found", expectedUri, docUri);
+        }
+        
+        // release client
+        client.release();
+   }
+	
+	/*public void testMultithreadingSearchAndWrite() throws InterruptedException
+	{
+		System.out.println("testMultithreadingSearchAndWrite");
+		
+		ThreadWrite tw1 = new ThreadWrite("Write Thread");
+		ThreadSearch ts1 = new ThreadSearch("Search Thread");
+
+        tw1.start(); 
+        ts1.start();
+        tw1.join();
+        ts1.join();
+        
+        DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+        TextDocumentManager docMgr = client.newTextDocumentManager();
+        
+        for (int i = 1; i <= 15; i++)
+        {
+        	String expectedUri = "/multithread-write/filename" + i + ".xml";
+        	String docUri = docMgr.exists("/multithread-write/filename" + i + ".xml").getUri();
+        	assertEquals("URI is not found", expectedUri, docUri);
+        }
+        
+        for(int x = 0; x <= 9; x++)
+        {
+        	System.out.println(ts1.totalResultsArray[x]);
+        	assertTrue("Search result is 0", ts1.totalResultsArray[x] != 0);
+        }
+        
+        // release client
+        client.release();
+   }*/
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testMultithreadingMultipleSearch() throws InterruptedException
+	{
+		System.out.println("testMultithreadingMultipleSearch");
+		
+		ThreadWrite tw1 = new ThreadWrite("Write Thread");
+		tw1.start();
+		tw1.join();
+		
+		ThreadSearch ts1 = new ThreadSearch("Search Thread 1");
+		ThreadSearch ts2 = new ThreadSearch("Search Thread 2");
+		ThreadSearch ts3 = new ThreadSearch("Search Thread 3");
+		ThreadSearch ts4 = new ThreadSearch("Search Thread 4");
+		ThreadSearch ts5 = new ThreadSearch("Search Thread 5");
+
+        ts1.start();
+        ts2.start();
+        ts3.start();
+        ts4.start();
+        ts5.start();
+        
+        ts1.join();
+        ts2.join();
+        ts3.join();
+        ts4.join();
+        ts5.join();
+        
+        long totalAllDocumentsReturned = ts1.totalAllResults + ts2.totalAllResults + ts3.totalAllResults + ts4.totalAllResults + ts5.totalAllResults;
+        assertTrue("Documents count is incorrect", totalAllDocumentsReturned == 750);
+   }
+	@AfterClass	
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+
+}
+
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestNamespaces.java b/test-complete/src/test/java/com/marklogic/javaclient/TestNamespaces.java
new file mode 100644
index 000000000..ac22d7c86
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestNamespaces.java
@@ -0,0 +1,166 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.xml.namespace.NamespaceContext;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.NamespacesManager;
+import com.marklogic.client.document.DocumentPatchBuilder;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.util.EditableNamespaceContext;
+import com.marklogic.client.util.RequestLogger;
+import org.junit.*;
+public class TestNamespaces extends BasicJavaClientREST {
+
+	private static String dbName = "TestNamespacesDB";
+	private static String [] fNames = {"TestNamespacesDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testNamespaces()
+	{	
+		System.out.println("Running testNamespaces");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create namespaces manager
+		NamespacesManager nsMgr = client.newServerConfigManager().newNamespacesManager();
+
+		// create logger
+		RequestLogger logger = client.newLogger(System.out);
+		logger.setContentMax(RequestLogger.ALL_CONTENT);
+	
+		// start logging
+		nsMgr.startLogging(logger);
+		
+		// add prefix
+		nsMgr.addPrefix("foo", "http://example.com");
+		
+		NamespaceContext nsContext = nsMgr.readAll();
+
+		assertEquals("Prefix is not equal", "foo", nsContext.getPrefix("http://example.com"));
+		assertEquals("Namespace URI is not equal", "http://example.com", nsContext.getNamespaceURI("foo"));
+		
+		// update prefix
+		nsMgr.updatePrefix("foo", "http://exampleupdated.com");
+		nsContext = nsMgr.readAll();
+		assertEquals("Updated Namespace URI is not equal", "http://exampleupdated.com", nsContext.getNamespaceURI("foo"));
+				
+		// stop logging
+		nsMgr.stopLogging();
+		
+		String expectedLogContentMax = "9223372036854775807"; 
+		assertEquals("Content log is not equal", expectedLogContentMax, Long.toString(logger.getContentMax()));
+		
+		// delete prefix
+		nsMgr.deletePrefix("foo");
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("foo") == null);
+		
+		nsMgr.deleteAll();
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("foo") == null);
+		
+		// release client
+		client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testDefaultNamespaces()
+	{
+		System.out.println("Running testDefaultNamespaces");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create namespaces manager
+		NamespacesManager nsMgr = client.newServerConfigManager().newNamespacesManager();
+		
+		// add namespaces
+		nsMgr.addPrefix("ns1", "http://foo.com");
+		nsMgr.addPrefix("ns2", "http://bar.com");
+		nsMgr.addPrefix("ns3", "http://baz.com");
+		
+		NamespaceContext context = nsMgr.readAll();
+		
+		// set default namespace
+		nsMgr.updatePrefix("defaultns", "http://baz.com");
+		String defaultNsUri = nsMgr.readPrefix("defaultns");
+		assertEquals("Default NS is wrong", "http://baz.com", defaultNsUri);
+				
+		// delete namespace
+		nsMgr.deletePrefix("baz");
+		context = nsMgr.readAll();
+		
+		// get default namespace
+		assertEquals("Default NS is wrong", "http://baz.com", nsMgr.readPrefix("defaultns"));
+		
+		nsMgr.deleteAll();
+		context = nsMgr.readAll();
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("ns1") == null);
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("ns2") == null);
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("ns3") == null);
+		assertTrue("Namespace URI is not deleted", nsMgr.readPrefix("defaultns") == null);
+		
+		// release client
+		client.release();
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug22396() throws IOException {
+
+		System.out.println("Runing testBug22396");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		writeDocumentUsingInputStreamHandle(client, "constraint1.xml", "/testBug22396/", "XML");
+
+		String docId = "/testBug22396/constraint1.xml";
+		
+		//create document manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		
+		//get namespaces 
+		Collection nameSpaceCollection = patchBldr.getNamespaces().getAllPrefixes();
+		assertEquals("getNamespace failed ",false, nameSpaceCollection.isEmpty());
+		for(String prefix : nameSpaceCollection){
+			System.out.println("Prefixes : "+prefix);
+			System.out.println(patchBldr.getNamespaces().getNamespaceURI(prefix));
+		}
+		//set namespace		
+		EditableNamespaceContext namespaces = new EditableNamespaceContext();
+		namespaces.put("new", "http://www.marklogic.com");
+		patchBldr.setNamespaces(namespaces);
+		System.out.println("\n Namespace Output : "+patchBldr.getNamespaces().getNamespaceURI("xmlns")+"\n Next xml : "+patchBldr.getNamespaces().getNamespaceURI("xml")+"\n Next xs : "+patchBldr.getNamespaces().getNamespaceURI("xs")+"\n Next xsi : "+patchBldr.getNamespaces().getNamespaceURI("xsi")+"\n Next rapi : "+patchBldr.getNamespaces().getNamespaceURI("rapi")+"\n Next new : "+patchBldr.getNamespaces().getNamespaceURI("new"));
+		String content = docMgr.read(docId, new StringHandle()).get();
+		assertTrue("setNamespace didn't worked", patchBldr.getNamespaces().getNamespaceURI("new").contains("www.marklogic.com"));
+		System.out.println(content);
+		
+		// release client
+		client.release();
+	}
+@AfterClass
+public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestOptimisticLocking.java b/test-complete/src/test/java/com/marklogic/javaclient/TestOptimisticLocking.java
new file mode 100644
index 000000000..34e89f7cf
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestOptimisticLocking.java
@@ -0,0 +1,646 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.FailedRequestException;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.ResourceNotFoundException;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.admin.ServerConfigurationManager.Policy;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.document.XMLDocumentManager;
+import org.junit.*;
+public class TestOptimisticLocking extends BasicJavaClientREST{
+
+	private static String dbName = "TestOptimisticLockingDB";
+	private static String [] fNames = {"TestOptimisticLockingDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testRequired() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testRequired");
+		
+		String filename = "xml-original.xml";
+		String updateFilename = "xml-updated.xml";
+		String uri = "/optimistic-locking/";
+		String docId = uri + filename;
+		long badVersion = 1111;
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for the server configuration
+		ServerConfigurationManager configMgr = client.newServerConfigManager();
+
+		// read the server configuration from the database
+		configMgr.readConfiguration();
+
+		// require content versions for updates and deletes
+		// use Policy.OPTIONAL to allow but not require versions
+		configMgr.setContentVersionRequests(Policy.REQUIRED);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+		System.out.println("set optimistic locking to required");
+		
+		// create document manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create document descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		desc.setVersion(badVersion);
+		
+		String exception = "";
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+		
+		// CREATE
+		// write document with bad version
+		try 
+		{
+			docMgr.write(desc, handle);
+		} catch (FailedRequestException e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// write document with unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+		docMgr.write(desc, handle);
+		
+		StringHandle readHandle = new StringHandle();
+		docMgr.read(desc, readHandle);
+		String content = readHandle.get();
+		assertTrue("Wrong content", content.contains("noodle"));
+		    	
+    	// get the good version
+    	long goodVersion = desc.getVersion();
+    	
+    	System.out.println("version before create: " + goodVersion);
+		
+    	// UPDATE
+		File updateFile = new File("src/test/java/com/marklogic/javaclient/data/" + updateFilename);
+
+		// create a handle on the content
+		FileHandle updateHandle = new FileHandle(updateFile);
+		updateHandle.set(updateFile);
+    	
+    	// update with bad version
+    	desc.setVersion(badVersion);
+    	
+		String updateException = "";
+		String expectedUpdateException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+
+    	try
+    	{
+    		docMgr.write(desc, updateHandle);
+    	} catch (FailedRequestException e) { updateException = e.toString(); }
+    	
+		boolean isUpdateExceptionThrown = updateException.contains(expectedUpdateException);
+		assertTrue("Exception is not thrown", isUpdateExceptionThrown);
+		
+		// update with unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+
+		String updateUnknownException = "";
+		String expectedUpdateUnknownException = "com.marklogic.client.FailedRequestException: Local message: Content version required to write document. Server Message: You do not have permission to this method and URL";
+
+		try
+		{
+			docMgr.write(desc, updateHandle);
+		} catch (FailedRequestException e) { updateUnknownException = e.toString(); }
+		
+		boolean isUpdateUnknownExceptionThrown = updateUnknownException.contains(expectedUpdateUnknownException);
+		assertTrue("Exception is not thrown", isUpdateUnknownExceptionThrown);
+
+		desc = docMgr.exists(docId);
+		goodVersion = desc.getVersion();
+		
+		System.out.println("version before update: " + goodVersion);
+		
+    	// update with good version
+		desc.setVersion(goodVersion);
+		docMgr.write(desc, updateHandle);
+		
+		StringHandle updateReadHandle = new StringHandle();
+		docMgr.read(desc, updateReadHandle);
+		String updateContent = updateReadHandle.get();
+		assertTrue("Wrong content", updateContent.contains("fried noodle"));
+		
+		// DELETE
+		// delete using bad version
+		desc.setVersion(badVersion);
+		
+		String deleteException = "";
+		String expectedDeleteException = "com.marklogic.client.FailedRequestException: Content version must match to delete document";
+		
+		try
+		{
+			docMgr.delete(desc);
+		} catch (FailedRequestException e) { deleteException = e.toString(); }
+		
+		boolean isDeleteExceptionThrown = deleteException.contains(expectedDeleteException);
+		assertTrue("Exception is not thrown", isDeleteExceptionThrown);
+		
+		// delete using unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+		
+		String deleteUnknownException = "";
+		String expectedDeleteUnknownException = "com.marklogic.client.FailedRequestException: Local message: Content version required to delete document. Server Message: You do not have permission to this method and URL";
+		
+		try
+		{
+			docMgr.delete(desc);
+		} catch (FailedRequestException e) { deleteUnknownException = e.toString(); }
+		
+		boolean isDeleteUnknownExceptionThrown = deleteUnknownException.contains(expectedDeleteUnknownException);
+		assertTrue("Exception is not thrown", isDeleteUnknownExceptionThrown);
+		
+		// delete using good version
+		desc = docMgr.exists(docId);
+		goodVersion = desc.getVersion();
+		
+		System.out.println("version before delete: " + goodVersion);
+		
+		docMgr.delete(desc);
+		
+		String verifyDeleteException = "";
+		String expectedVerifyDeleteException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document";
+		
+		StringHandle deleteHandle = new StringHandle();
+		try
+		{
+			docMgr.read(desc, deleteHandle);
+		} catch (ResourceNotFoundException e) { verifyDeleteException = e.toString(); }
+		
+		boolean isVerifyDeleteExceptionThrown = verifyDeleteException.contains(expectedVerifyDeleteException);
+		assertTrue("Exception is not thrown", isVerifyDeleteExceptionThrown);
+		
+		// release client
+		client.release();
+		
+		try {
+			Thread.sleep(30000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		
+		System.out.println(configMgr.getContentVersionRequests());
+
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testOptionalWithUnknownVersion() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testOptionalWithUnknownVersion");
+		
+		String filename = "json-original.json";
+		String updateFilename = "json-updated.json";
+		String uri = "/optimistic-locking/";
+		String docId = uri + filename;
+		long badVersion = 1111;
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for the server configuration
+		ServerConfigurationManager configMgr = client.newServerConfigManager();
+
+		// read the server configuration from the database
+		configMgr.readConfiguration();
+
+		// use Policy.OPTIONAL to allow but not require versions
+		configMgr.setContentVersionRequests(Policy.OPTIONAL);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+		System.out.println("set optimistic locking to optional");
+		
+		// create document manager
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create document descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		desc.setVersion(badVersion);
+		
+		String exception = "";
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+		
+		// CREATE
+		// write document with bad version
+		try 
+		{
+			docMgr.write(desc, handle);
+		} catch (FailedRequestException e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// write document with unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+		docMgr.write(desc, handle);
+		
+		StringHandle readHandle = new StringHandle();
+		docMgr.read(desc, readHandle);
+		String content = readHandle.get();
+		assertTrue("Wrong content", content.contains("John"));
+		    	
+    	// get the unknown version
+    	long unknownVersion = desc.getVersion();
+    	
+    	System.out.println("unknown version after create: " + unknownVersion);
+		
+    	// UPDATE
+		File updateFile = new File("src/test/java/com/marklogic/javaclient/data/" + updateFilename);
+
+		// create a handle on the content
+		FileHandle updateHandle = new FileHandle(updateFile);
+		updateHandle.set(updateFile);
+    	
+    	// update with bad version
+    	desc.setVersion(badVersion);
+    	
+		String updateException = "";
+		String expectedUpdateException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+
+    	try
+    	{
+    		docMgr.write(desc, updateHandle);
+    	} catch (FailedRequestException e) { updateException = e.toString(); }
+    	
+		boolean isUpdateExceptionThrown = updateException.contains(expectedUpdateException);
+		assertTrue("Exception is not thrown", isUpdateExceptionThrown);
+		
+		// update with unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+		
+		docMgr.write(desc, updateHandle);
+				
+		StringHandle updateReadHandle = new StringHandle();
+		docMgr.read(desc, updateReadHandle);
+		String updateContent = updateReadHandle.get();
+		assertTrue("Wrong content", updateContent.contains("Aries"));
+		
+		unknownVersion = desc.getVersion();
+    	
+    	System.out.println("unknown version after update: " + unknownVersion);
+    	
+    	// read using matched version
+    	desc.setVersion(unknownVersion);
+    	StringHandle readMatchHandle = new StringHandle();
+    	docMgr.read(desc, readMatchHandle);
+    	String readMatchContent = readMatchHandle.get();
+    	assertTrue("Document does not return null", readMatchContent == null);
+    	
+		// DELETE
+		// delete using bad version
+		desc.setVersion(badVersion);
+		
+		String deleteException = "";
+		String expectedDeleteException = "com.marklogic.client.FailedRequestException: Content version must match to delete document";
+		
+		try
+		{
+			docMgr.delete(desc);
+		} catch (FailedRequestException e) { deleteException = e.toString(); }
+		
+		boolean isDeleteExceptionThrown = deleteException.contains(expectedDeleteException);
+		assertTrue("Exception is not thrown", isDeleteExceptionThrown);
+		
+		// delete using unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);		
+		docMgr.delete(desc);
+		
+		unknownVersion = desc.getVersion();
+		
+		System.out.println("unknown version after delete: " + unknownVersion);
+		
+		String verifyDeleteException = "";
+		String expectedVerifyDeleteException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document";
+		
+		StringHandle deleteHandle = new StringHandle();
+		try
+		{
+			docMgr.read(desc, deleteHandle);
+		} catch (ResourceNotFoundException e) { verifyDeleteException = e.toString(); }
+		
+		boolean isVerifyDeleteExceptionThrown = verifyDeleteException.contains(expectedVerifyDeleteException);
+		assertTrue("Exception is not thrown", isVerifyDeleteExceptionThrown);
+		
+		// release client
+		client.release();
+		
+		try {
+			Thread.sleep(30000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		
+		System.out.println(configMgr.getContentVersionRequests());
+
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test	
+	public void testOptionalWithGoodVersion() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testOptionalWithGoodVersion");
+		
+		String filename = "json-original.json";
+		String updateFilename = "json-updated.json";
+		String uri = "/optimistic-locking/";
+		String docId = uri + filename;
+		long badVersion = 1111;
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for the server configuration
+		ServerConfigurationManager configMgr = client.newServerConfigManager();
+
+		// read the server configuration from the database
+		configMgr.readConfiguration();
+
+		// use Policy.OPTIONAL to allow but not require versions
+		configMgr.setContentVersionRequests(Policy.OPTIONAL);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+		System.out.println("set optimistic locking to optional");
+		
+		// create document manager
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create document descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		desc.setVersion(badVersion);
+		
+		String exception = "";
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+		
+		// CREATE
+		// write document with bad version
+		try 
+		{
+			docMgr.write(desc, handle);
+		} catch (FailedRequestException e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// write document with unknown version
+		desc.setVersion(DocumentDescriptor.UNKNOWN_VERSION);
+		docMgr.write(desc, handle);
+		
+		StringHandle readHandle = new StringHandle();
+		docMgr.read(desc, readHandle);
+		String content = readHandle.get();
+		assertTrue("Wrong content", content.contains("John"));
+		    	
+    	// get the good version
+    	long goodVersion = desc.getVersion();
+    	
+    	System.out.println("good version after create: " + goodVersion);
+		
+    	// UPDATE
+		File updateFile = new File("src/test/java/com/marklogic/javaclient/data/" + updateFilename);
+
+		// create a handle on the content
+		FileHandle updateHandle = new FileHandle(updateFile);
+		updateHandle.set(updateFile);
+    	
+    	// update with bad version
+    	desc.setVersion(badVersion);
+    	
+		String updateException = "";
+		String expectedUpdateException = "com.marklogic.client.FailedRequestException: Local message: Content version must match to write document. Server Message: RESTAPI-CONTENTWRONGVERSION";
+
+    	try
+    	{
+    		docMgr.write(desc, updateHandle);
+    	} catch (FailedRequestException e) { updateException = e.toString(); }
+    	
+		boolean isUpdateExceptionThrown = updateException.contains(expectedUpdateException);
+		assertTrue("Exception is not thrown", isUpdateExceptionThrown);
+		
+		// update with good version
+		desc.setVersion(goodVersion);
+		
+		docMgr.write(desc, updateHandle);
+				
+		StringHandle updateReadHandle = new StringHandle();
+		docMgr.read(desc, updateReadHandle);
+		String updateContent = updateReadHandle.get();
+		assertTrue("Wrong content", updateContent.contains("Aries"));
+		
+		goodVersion = desc.getVersion();
+    	
+    	System.out.println("good version after update: " + goodVersion);
+    	
+    	// read using matched version
+    	desc.setVersion(goodVersion);
+    	StringHandle readMatchHandle = new StringHandle();
+    	docMgr.read(desc, readMatchHandle);
+    	String readMatchContent = readMatchHandle.get();
+    	assertTrue("Document does not return null", readMatchContent == null);
+    	
+		// DELETE
+		// delete using bad version
+		desc.setVersion(badVersion);
+		
+		String deleteException = "";
+		String expectedDeleteException = "com.marklogic.client.FailedRequestException: Content version must match to delete document";
+		
+		try
+		{
+			docMgr.delete(desc);
+		} catch (FailedRequestException e) { deleteException = e.toString(); }
+		
+		boolean isDeleteExceptionThrown = deleteException.contains(expectedDeleteException);
+		assertTrue("Exception is not thrown", isDeleteExceptionThrown);
+		
+		// delete using good version
+		desc.setVersion(goodVersion);		
+		docMgr.delete(desc);
+		
+		goodVersion = desc.getVersion();
+		
+		System.out.println("unknown version after delete: " + goodVersion);
+		
+		String verifyDeleteException = "";
+		String expectedVerifyDeleteException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document";
+		
+		StringHandle deleteHandle = new StringHandle();
+		try
+		{
+			docMgr.read(desc, deleteHandle);
+		} catch (ResourceNotFoundException e) { verifyDeleteException = e.toString(); }
+		
+		boolean isVerifyDeleteExceptionThrown = verifyDeleteException.contains(expectedVerifyDeleteException);
+		assertTrue("Exception is not thrown", isVerifyDeleteExceptionThrown);
+		
+		// release client
+		client.release();
+		
+		try {
+			Thread.sleep(30000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		
+		System.out.println(configMgr.getContentVersionRequests());
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testNone() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testNone");
+		
+		String filename = "json-original.json";
+		String updateFilename = "json-updated.json";
+		String uri = "/optimistic-locking/";
+		String docId = uri + filename;
+		long badVersion = 1111;
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for the server configuration
+		ServerConfigurationManager configMgr = client.newServerConfigManager();
+
+		// read the server configuration from the database
+		configMgr.readConfiguration();
+
+		// use Policy.NONE
+		configMgr.setContentVersionRequests(Policy.NONE);
+
+		// write the server configuration to the database
+		configMgr.writeConfiguration();
+
+		System.out.println("set optimistic locking to none");
+		
+		// create document manager
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create document descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		desc.setVersion(badVersion);
+		
+		// CREATE
+		// write document with bad version
+		
+		docMgr.write(desc, handle);
+		
+		StringHandle readHandle = new StringHandle();
+		docMgr.read(desc, readHandle);
+		String content = readHandle.get();
+		assertTrue("Wrong content", content.contains("John"));
+		    			
+    	// UPDATE
+		File updateFile = new File("src/test/java/com/marklogic/javaclient/data/" + updateFilename);
+
+		// create a handle on the content
+		FileHandle updateHandle = new FileHandle(updateFile);
+		updateHandle.set(updateFile);
+    	
+    	// update with bad version
+    	desc.setVersion(badVersion);
+    	
+    	docMgr.write(desc, updateHandle);
+				
+		StringHandle updateReadHandle = new StringHandle();
+		docMgr.read(desc, updateReadHandle);
+		String updateContent = updateReadHandle.get();
+		assertTrue("Wrong content", updateContent.contains("Aries"));
+		    	
+		// DELETE
+		// delete using bad version
+		desc.setVersion(badVersion);
+		
+		docMgr.delete(desc);
+		
+		String verifyDeleteException = "";
+		String expectedVerifyDeleteException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document";
+		
+		StringHandle deleteHandle = new StringHandle();
+		try
+		{
+			docMgr.read(desc, deleteHandle);
+		} catch (ResourceNotFoundException e) { verifyDeleteException = e.toString(); }
+		
+		boolean isVerifyDeleteExceptionThrown = verifyDeleteException.contains(expectedVerifyDeleteException);
+		assertTrue("Exception is not thrown", isVerifyDeleteExceptionThrown);
+		
+		// release client
+		client.release();
+		
+		try {
+			Thread.sleep(30000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		
+		System.out.println(configMgr.getContentVersionRequests());
+	}
+	@AfterClass
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestOutputStreamHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestOutputStreamHandle.java
new file mode 100644
index 000000000..1b297e7cb
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestOutputStreamHandle.java
@@ -0,0 +1,306 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.OutputStreamHandle;
+import com.marklogic.client.io.OutputStreamSender;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestOutputStreamHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "OutputStreamHandleDB";
+	private static String [] fNames = {"OutputStreamHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	@BeforeClass
+	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-outputstreamhandle/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+	
+		// write docs
+		writeDocumentUsingOutputStreamHandle(client, filename, uri, "XML");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri+filename, "XML");
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		String readContent = convertInputStreamToString(fileRead);
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    	// acquire the content for update
+	    	String updateFilename = "xml-updated-test.xml";
+	    	updateDocumentUsingOutputStreamHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    	// read the document
+	    	InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	 
+	    	// get the contents
+	    	InputStream fileReadUpdate = updateHandle.get();
+	    	
+	    	String readContentUpdate = convertInputStreamToString(fileReadUpdate);
+
+	    	// get xml document for expected result
+	    	Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+	    	// convert actual string to xml doc
+	    	Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    	assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+	    
+		// release client
+		client.release();
+	}
+	
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testTextCRUD() throws IOException
+	{	
+		String filename = "text-original.txt";
+		String uri = "/write-text-outputstreamhandle/";
+		
+		System.out.println("Running testTextCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingOutputStreamHandle(client, filename, uri, "Text");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		
+		String readContent = convertInputStreamToString(fileRead);
+		
+		String expectedContent = "hello world, welcome to java API";
+						
+		assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "text-updated.txt";
+	    updateDocumentUsingOutputStreamHandle(client, updateFilename, uri + filename, "Text");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+		
+		String readContentUpdate = convertInputStreamToString(fileReadUpdate);
+		
+		String expectedContentUpdate = "hello world, welcome to java API after new updates";
+		
+		assertEquals("Write Text difference", expectedContentUpdate.trim(), readContentUpdate.toString().trim());
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "Text");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Text"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Text");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testJsonCRUD() throws IOException
+	{	
+		String filename = "json-original.json";
+		String uri = "/write-json-outputstreamhandle/";
+		
+		System.out.println("Running testJsonCRUD");
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingOutputStreamHandle(client, filename, uri, "JSON");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		JsonNode readContent = mapper.readTree(fileRead);
+		
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+		
+		assertTrue("Write JSON document difference", readContent.equals(expectedContent));
+		
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "json-updated.json";
+	    updateDocumentUsingOutputStreamHandle(client, updateFilename, uri + filename, "JSON");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+
+		JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+		
+		// get expected contents
+		JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+		
+		assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "JSON");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "JSON"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "JSON");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+		// release client
+		client.release();
+	}
+	
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testBinaryCRUD() throws IOException
+	{	
+		String filename = "Pandakarlino.jpg";
+		String uri = "/write-bin-outputstreamhandle/";
+		
+		System.out.println("Running testBinaryCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		writeDocumentUsingOutputStreamHandle(client, filename, uri, "Binary");
+				
+		// read docs
+		InputStreamHandle contentHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");
+		
+		// get the contents
+		InputStream fileRead = contentHandle.get();
+		
+		// get the binary size
+		int size = getBinarySize(fileRead);
+		int expectedSize = 17154;
+		
+		assertEquals("Binary size difference", expectedSize, size);
+		
+		// update the doc
+	    // acquire the content for update
+	    String updateFilename = "mlfavicon.png";
+	    updateDocumentUsingOutputStreamHandle(client, updateFilename, uri + filename, "Binary");
+	    
+	    // read the document
+	    InputStreamHandle updateHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");				
+		
+		// get the contents
+		InputStream fileReadUpdate = updateHandle.get();
+		
+		// get the binary size
+		int sizeUpdate = getBinarySize(fileReadUpdate);
+		int expectedSizeUpdate = 3322;
+	    
+		assertEquals("Binary size difference", expectedSizeUpdate, sizeUpdate);
+		
+		// delete the document
+	    deleteDocument(client, uri + filename, "Binary");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Binary"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "Binary");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+			    
+	    // release client
+		client.release();
+	}
+@AfterClass	
+	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestPartialUpdate.java b/test-complete/src/test/java/com/marklogic/javaclient/TestPartialUpdate.java
new file mode 100644
index 000000000..c303fd88c
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestPartialUpdate.java
@@ -0,0 +1,858 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.javaclient.TestCRUDModulesDb;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ExtensionLibrariesManager;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.DocumentMetadataPatchBuilder;
+import com.marklogic.client.document.DocumentPatchBuilder;
+import com.marklogic.client.document.DocumentUriTemplate;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.document.DocumentMetadataPatchBuilder.Cardinality;
+import com.marklogic.client.document.DocumentPatchBuilder.Position;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+import com.marklogic.client.io.marker.DocumentPatchHandle;
+import com.marklogic.client.query.StructuredQueryBuilder.FragmentScope;
+import com.marklogic.client.query.ValuesDefinition.Frequency;
+import org.junit.*;
+
+
+public class TestPartialUpdate extends BasicJavaClientREST {
+
+	private static String dbName = "TestPartialUpdateDB";
+	private static String [] fNames = {"TestPartialUpdateDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testPartialUpdateXML() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateXML");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		}
+		
+		String docId = "/partial-update/constraint1.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		
+		patchBldr.insertFragment("/root", Position.LAST_CHILD, "2013-03-21");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("2013-03-21"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateJSON() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateJSON");
+		
+		String[] filenames = {"json-original.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "JSON");
+		}
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		String docId = "/partial-update/json-original.json";
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		
+		ObjectNode fragmentNode = mapper.createObjectNode();
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("insertedKey", 9);
+		String fragment = mapper.writeValueAsString(fragmentNode);
+		
+		patchBldr.insertFragment("$.employees", Position.LAST_CHILD, fragment);
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("{\"insertedKey\":9}]"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateContent() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateContent");
+		
+		String filename = "constraint1.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		
+		String docId = "/partial-update/constraint1.xml";
+		
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		
+		////
+		//Updating Content
+		////
+		//Inserting Node
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root", Position.LAST_CHILD, "2013-03-21");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(" Before Updating "+ contentBefore );
+
+		//Updating inserted Node
+		DocumentPatchBuilder xmlPatchBldr = xmlDocMgr.newPatchBuilder();
+		DocumentPatchHandle xmlPatchForNode = xmlPatchBldr.replaceFragment("/root/modified", "2012-11-5").build();
+		xmlDocMgr.patch(docId, xmlPatchForNode);
+		String contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Updating" + contentAfter);
+		
+		assertTrue("fragment is not inserted", contentAfter.contains("2012-11-5"));
+		
+		////
+		//Updating Doc Element
+		////
+		String contentBeforeElement = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBeforeElement );
+		DocumentPatchHandle xmlPatchForElement = xmlPatchBldr.replaceValue("/root/popularity", 10).build();
+		xmlDocMgr.patch(docId, xmlPatchForElement);
+		contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Updating" + contentAfter);
+		
+		//Check
+		assertTrue("Element Value has not Changed", contentAfter.contains("10"));
+		
+		////
+		//Updating Doc Attribute
+		////
+		String contentBeforeAttribute = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBeforeAttribute );
+
+		//Updating Attribute Value
+		xmlPatchBldr.replaceValue("/root/*:price/@amt",0.5);
+		//xmlPatchBldr.replaceValue("/root/*:price/@xmlns","http://marklogic.com");
+		DocumentPatchHandle xmlPatchForValue = xmlPatchBldr.build();
+		xmlDocMgr.patch(docId, xmlPatchForValue);
+		contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Updating" + contentAfter);
+		//Check
+		assertTrue("Value of amt has not Chenged", contentAfter.contains(""));
+		
+		
+		////
+		//Updating Doc Namespace
+		////
+		String contentBeforeNamespace = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBeforeNamespace );
+
+		//Changing Element Value
+		DocumentPatchHandle xmlPatch = xmlPatchBldr.replaceValue("/root/*:date", "2006-02-02").build();
+		xmlDocMgr.patch(docId, xmlPatch);
+		contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Updating" + contentAfter);
+		//Check
+		assertTrue("Element Value has not Changed", contentAfter.contains("2006-02-02"));
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateDeletePath() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateDeletePath");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+		
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+
+		//Deleting Element Value
+		DocumentPatchBuilder xmlPatchBldr = xmlDocMgr.newPatchBuilder();
+		//DocumentPatchHandle xmlPatch = xmlPatchBldr.replaceValue("/root/*:date", "2006-02-02").build();
+		DocumentPatchHandle xmlPatch = xmlPatchBldr.delete("/root/*:date").build();
+		xmlDocMgr.patch(docId, xmlPatch);
+		
+		//Delete invalid Path
+		try{
+		xmlPatch = xmlPatchBldr.delete("InvalidPath").build();
+		xmlDocMgr.patch(docId, xmlPatch);
+		}
+		catch (Exception e){
+			System.out.println(e.toString());
+			assertTrue("Haven't deleted Invalid path", e.toString().contains(" invalid path: //InvalidPath"));
+		}
+		String contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Updating" + contentAfter);
+		assertFalse("Element is not Deleted", contentAfter.contains("2005-01-01"));
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateFragments() throws Exception{
+		System.out.println("Running testPartialUpdateFragments");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+		//Inserting Fragments with valid path
+		DocumentPatchBuilder patchBldr = xmlDocMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/title", Position.BEFORE , "Hi\n  ");
+		patchBldr.insertFragment("/root/id", Position.AFTER , "\n  2013-03-21");
+		patchBldr.insertFragment("/root", Position.LAST_CHILD , "  bye\n");
+		//Inserting Fragments with invalid path
+		patchBldr.insertFragment("/root/someinvalidpath", Position.BEFORE, "Entry");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		xmlDocMgr.patch(docId, patchHandle);
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted Before", content.contains("Hi"));
+		assertTrue("fragment is not inserted After", content.contains("2013-03-21"));
+		assertTrue("fragment is not inserted as Last Child", content.contains("bye"));
+		assertFalse("fragment with invalid path has entered", content.contains("Entry"));
+		// release client
+		client.release();	
+		
+	
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateInsertFragments() throws Exception{
+		System.out.println("Running testPartialUpdateInsertFragments");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+		//Replacing Fragments with valid path
+		DocumentPatchBuilder patchBldr = xmlDocMgr.newPatchBuilder();
+		patchBldr.replaceFragment("/root/title", "foo");
+		//Replacing Fragments with invalid path
+		patchBldr.replaceFragment("/root/invalidpath", "FalseEntry");
+		patchBldr.replaceInsertFragment("/root/nonexist", "/root", Position.LAST_CHILD, "  bar\n ");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		xmlDocMgr.patch(docId, patchHandle);
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not Replaced", content.contains("foo"));
+		assertFalse("fragment is not Replaced", content.contains("FalseEntry"));
+		assertTrue("replaceInsertFragment has Failed", content.contains("bar"));
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateInsertExistingFragments() throws Exception{
+		System.out.println("Running testPartialUpdateInsertExistingFragments");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+		//Replacing Fragments with valid path
+		DocumentPatchBuilder patchBldr = xmlDocMgr.newPatchBuilder();
+		patchBldr.replaceInsertFragment("/root/title", "/root", Position.LAST_CHILD, "LastChild");
+		patchBldr.replaceInsertFragment("/root/id", "/root", Position.BEFORE, "Before");
+		patchBldr.replaceInsertFragment("/root/p", "/root", Position.AFTER, "After");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		xmlDocMgr.patch(docId, patchHandle);
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("replaceInsertFragment Failed at Position.LAST_CHILD", content.contains("LastChild"));
+		assertTrue("replaceInsertFragment Failed at Position.BEFORE", content.contains("Before"));
+		assertTrue("replaceInsertFragment Failed at Position.AFTER", content.contains("After"));
+
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateReplaceApply() throws Exception{
+		System.out.println("Running testPartialUpdateReplaceApply");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		ExtensionLibrariesManager libsMgr =  client.newServerConfigManager().newExtensionLibrariesManager();
+	
+		libsMgr.write("/ext/patch/custom-lib.xqy", new FileHandle(new File("src/test/java/com/marklogic/javaclient/data/custom-lib.xqy")).withFormat(Format.TEXT));
+		// write docs
+		String filename = "constraint6.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		//writeDocumentUsingInputStreamHandle(client, "custom-lib.xqy", "/partial-update/", "XML");
+		String docId = "/partial-update/constraint6.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+		// Executing different operations on XML
+		DocumentPatchBuilder patchBldr = xmlDocMgr.newPatchBuilder();
+		patchBldr.replaceApply("/root/add", patchBldr.call().add(10));
+		patchBldr.replaceApply("/root/subtract", patchBldr.call().subtract(2));
+		patchBldr.replaceApply("/root/multiply", patchBldr.call().multiply(2));
+		patchBldr.replaceApply("/root/divide", patchBldr.call().divideBy(2));
+		patchBldr.replaceApply("/root/concatenateAfter", patchBldr.call().concatenateAfter(" ML7"));
+		patchBldr.replaceApply("/root/concatenateBetween", patchBldr.call().concatenateBetween("ML "," 7"));
+		patchBldr.replaceApply("/root/concatenateBefore", patchBldr.call().concatenateBefore("ML "));
+		patchBldr.replaceApply("/root/substringAfter", patchBldr.call().substringAfter("Version"));
+		patchBldr.replaceApply("/root/substringBefore", patchBldr.call().substringBefore("Version"));
+		patchBldr.replaceApply("/root/replaceRegex", patchBldr.call().replaceRegex("[a-m]","1"));
+		patchBldr.replaceApply("/root/applyLibrary", patchBldr.call().applyLibraryFragments("underwrite","API")).library("http://marklogic.com/ext/patch/custom-lib","/ext/patch/custom-lib.xqy");
+		//patchBldr.replaceApply("/root/applyLibrary", patchBldr.call().applyLibraryValues("any-content","")).library("http://marklogic.com/ext/patch/custom-lib","/ext/patch/custom-lib.xqy");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		xmlDocMgr.patch(docId, patchHandle);
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After Update" + content);
+		//Check
+		assertTrue("Add Failed", content.contains("15"));
+		assertTrue("Subtract Failed", content.contains("3"));
+		assertTrue("Multiplication Failed", content.contains("4"));
+		assertTrue("Division Failed", content.contains("10"));
+		assertTrue("concatenateAfter Failed", content.contains("Hi ML7"));
+		assertTrue("concatenateBefore Failed", content.contains("ML 7"));
+		assertTrue("substringAfter Failed", content.contains("  7"));
+		assertTrue("substringBefore Failed", content.contains("ML "));
+		assertTrue("concatenateBetween Failed", content.contains("ML Version 7"));
+		assertTrue("Ragex Failed", content.contains("C111nt"));
+		assertTrue("Apply Library Fragments Failed ", content.contains("APIAPI"));
+		// release client
+		libsMgr.delete("/ext/patch/custom-lib.xqy");
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	 public void testPartialUpdateCombination() throws Exception{
+		System.out.println("Running testPartialUpdateCombination");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+	
+		DocumentPatchBuilder xmlPatchBldr = xmlDocMgr.newPatchBuilder();
+		DocumentPatchHandle xmlPatch = xmlPatchBldr.insertFragment("/root", Position.LAST_CHILD, "2012-11-5").delete("/root/*:date").replaceApply("/root/popularity", xmlPatchBldr.call().multiply(2)).build();
+		xmlDocMgr.patch(docId, xmlPatch);
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(" After Updating "+ content);
+		//Check
+		assertTrue("Multiplication Failed", content.contains("10"));
+		assertFalse("Deletion Failed", content.contains("2005-01-01"));
+		assertTrue("Insertion Failed", content.contains("2012-11-5"));
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateCombinationTransc() throws Exception{
+		System.out.println("Running testPartialUpdateCombination");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		Transaction t = client.openTransaction("Transac");
+		// write docs
+		String filename = "constraint1.xml";
+		//writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/","XML");
+		//t.commit();
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentBefore );
+		//Transaction t1 = client.openTransaction();
+		DocumentPatchBuilder xmlPatchBldr = xmlDocMgr.newPatchBuilder();
+		DocumentPatchHandle xmlPatch = xmlPatchBldr.insertFragment("/root", Position.LAST_CHILD, "2012-11-5").delete("/root/*:date").replaceApply("/root/popularity", xmlPatchBldr.call().multiply(2)).build();
+		xmlDocMgr.patch(docId, xmlPatch,t);
+		t.commit();
+		String content = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(" After Updating "+ content);
+		
+		//Check
+		assertTrue("Multiplication Failed", content.contains("10"));
+		assertFalse("Deletion Failed", content.contains("2005-01-01"));
+		assertTrue("Insertion Failed", content.contains("2012-11-5"));
+		
+		// release client
+		client.release();		
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateCombinationTranscRevert() throws Exception{
+		System.out.println("Running testPartialUpdateCombinationTranscRevert");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		// write docs
+		String[] filenames = {"constraint1.xml", "constraint2.xml"};
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		}
+		String docId1= "/partial-update/constraint1.xml";
+		String docId2 = "/partial-update/constraint2.xml";
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr1 = client.newXMLDocumentManager();
+		XMLDocumentManager xmlDocMgr2= client.newXMLDocumentManager();
+		String contentBefore1 = xmlDocMgr1.read(docId1, new StringHandle()).get();
+		String contentBefore2 = xmlDocMgr2.read(docId2, new StringHandle()).get();
+		System.out.println(" Before Updating Document 1 "+ contentBefore1 );
+		System.out.println(" Before Updating Document 2 "+ contentBefore2 );
+		
+		DocumentPatchBuilder xmlPatchBldr1 = xmlDocMgr1.newPatchBuilder();
+		DocumentPatchBuilder xmlPatchBldr2 = xmlDocMgr2.newPatchBuilder();
+		
+		DocumentPatchHandle xmlPatch1 = xmlPatchBldr1.insertFragment("/root", Position.LAST_CHILD, "2012-11-5").build();
+		DocumentPatchHandle xmlPatch2 = xmlPatchBldr2.insertFragment("/root", Position.LAST_CHILD, "2012-11-5").build();
+		
+		Transaction t1 = client.openTransaction();
+		xmlDocMgr1.patch(docId1, xmlPatch1,t1);
+		t1.commit();
+		String content1 = xmlDocMgr1.read(docId1, new StringHandle()).get();
+		System.out.println(" After Updating Documant 1 : Transaction Commit"+ content1);
+		Transaction t2 = client.openTransaction();
+		xmlDocMgr1.patch(docId2, xmlPatch2,t2);
+		t2.rollback();
+		
+		String content2 = xmlDocMgr2.read(docId2, new StringHandle()).get();
+		System.out.println(" After Updating Document 2 : Transaction Rollback"+ content2);
+		
+		//Check
+//		assertTrue("Insertion Failed", content.contains("2012-11-5"));
+
+		// release client
+		client.release();		
+		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateCombinationJSON() throws Exception{
+		System.out.println("Running testPartialUpdateCombinationJSON");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String[] filenames = {"json-original.json"};
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "JSON");
+		}
+		String docId = "/partial-update/json-original.json";
+		
+		ObjectMapper mapper = new ObjectMapper();
+
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		String content1 = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("Before" + content1);
+		ObjectNode fragmentNode = mapper.createObjectNode();
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("insertedKey", 9);
+		String fragment = mapper.writeValueAsString(fragmentNode);
+		patchBldr.insertFragment("$.employees", Position.LAST_CHILD, fragment).delete("$.employees[2]").replaceApply("$.employees[1].firstName", patchBldr.call().concatenateAfter("Hi"));
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After" + content);
+		
+		assertTrue("fragment is not inserted", content.contains("{\"insertedKey\":9}]"));
+		assertTrue("fragment is not inserted", content.contains("{\"firstName\":\"AnnHi\", \"lastName\":\"Smith\"}"));
+		assertFalse("fragment is not deleted",content.contains("{\"firstName\":\"Bob\", \"lastName\":\"Foo\"}"));
+		// release client
+		client.release();	
+				
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateMetadata() throws Exception{
+		System.out.println("Running testPartialUpdateMetadata");
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		String filename = "constraint1.xml";
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		String docId = "/partial-update/constraint1.xml";
+
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		String contentMetadata = xmlDocMgr.readMetadata(docId, new StringHandle()).get();
+		System.out.println(" Before Updating "+ contentMetadata);
+		
+		DocumentMetadataPatchBuilder patchBldr = xmlDocMgr.newPatchBuilder(Format.XML);
+		patchBldr.addCollection("/document/collection3");
+		patchBldr.addPermission("admin", Capability.READ);
+		patchBldr.addPropertyValue("Hello","Hi");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		xmlDocMgr.patch(docId, patchHandle);
+	
+		String contentMetadata1 = xmlDocMgr.readMetadata(docId, new StringHandle()).get();
+		System.out.println(" After Changing "+ contentMetadata1);
+		
+		//Check
+		assertTrue("Collection not added", contentMetadata1.contains("/document/collection3"));
+		assertTrue("Permission not added", contentMetadata1.contains("admin"));
+		assertTrue("Property not added", contentMetadata1.contains("Hi"));
+		
+		////
+		//replacing Metadata Values
+		////
+		DocumentMetadataPatchBuilder patchBldrRep = xmlDocMgr.newPatchBuilder(Format.XML);
+		patchBldrRep.replaceCollection("/document/collection3", "/document/collection4");
+		patchBldrRep.replacePermission("admin",Capability.UPDATE);
+		patchBldrRep.replacePropertyValue("Hello", "Bye");
+		DocumentPatchHandle patchHandleRep = patchBldrRep.build();
+		xmlDocMgr.patch(docId, patchHandleRep);
+		String contentMetadataRep = xmlDocMgr.readMetadata(docId, new StringHandle()).get();
+		System.out.println(" After Updating "+ contentMetadataRep);
+		
+		//Check
+		assertTrue("Collection not added", contentMetadataRep.contains("/document/collection4"));
+		assertTrue("Permission not added", contentMetadataRep.contains("admin"));
+		assertTrue("Property not added", contentMetadataRep.contains("Bye"));
+	
+		////
+		//Deleting Metadata Values
+		////
+		DocumentMetadataPatchBuilder patchBldrDel = xmlDocMgr.newPatchBuilder(Format.XML);
+		patchBldrDel.deleteCollection("/document/collection4");
+		patchBldrDel.deletePermission("admin");
+		patchBldrDel.deleteProperty("Hello");
+		DocumentPatchHandle patchHandleDel = patchBldrDel.build();
+		xmlDocMgr.patch(docId, patchHandleDel);
+		String contentMetadataDel = xmlDocMgr.readMetadata(docId, new StringHandle()).get();
+		System.out.println(" After Deleting "+ contentMetadataDel);
+		
+		//Check
+		assertFalse("Collection not deleted", contentMetadataDel.contains("/document/collection4"));
+		assertFalse("Permission not deleted", contentMetadataDel.contains("admin"));
+		assertFalse("Property not deleted", contentMetadataDel.contains("Bye"));
+			
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateXMLDscriptor() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateXMLDescriptor");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		}
+
+		String docId = "/partial-update/constraint1.xml";
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+		//Create Document Descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root", Position.LAST_CHILD, "2013-03-21");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		
+		docMgr.patch(desc, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After"+content);
+		
+		assertTrue("fragment is not inserted", content.contains("2013-03-21"));
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateJSONDescriptor() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateJSONDescriptor");
+		
+		String[] filenames = {"json-original.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "JSON");
+		}
+		
+		
+		
+		ObjectMapper mapper = new ObjectMapper();
+		String docId = "/partial-update/json-original.json";
+		// create doc manager
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+
+		//Create Document Descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(docId);
+		
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		
+		ObjectNode fragmentNode = mapper.createObjectNode();
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("insertedKey", 9);
+		String fragment = mapper.writeValueAsString(fragmentNode);
+		
+		patchBldr.insertFragment("$.employees", Position.LAST_CHILD, fragment);
+		DocumentPatchHandle patchHandle = patchBldr.build();
+
+		docMgr.patch(desc, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After"+content);
+		
+		assertTrue("fragment is not inserted", content.contains("{\"insertedKey\":9}]"));
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateXMLDscriptorTranc() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateXMLDescriptorTranc");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		}
+
+		String docId = "/partial-update/constraint1.xml";
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		// create template
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("xml");
+		template.withDirectory(docId);
+
+		DocumentDescriptor desc = docMgr.newDescriptor(template.getDirectory());
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root", Position.LAST_CHILD, "2013-03-21");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		Transaction t = client.openTransaction("Tranc");
+		docMgr.patch(desc, patchHandle, t);
+		t.commit();
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After"+content);
+		
+		assertTrue("fragment is not inserted", content.contains("2013-03-21"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateJSONDescriptorTranc() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateJSONDescriptorTranc");
+		
+		String[] filenames = {"json-original.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "JSON");
+		}
+		ObjectMapper mapper = new ObjectMapper();
+		String docId = "/partial-update/json-original.json";
+		// create doc manager
+		JSONDocumentManager docMgr = client.newJSONDocumentManager();
+		// create template
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("JSON");
+		template.withDirectory(docId);
+		//Create Document Descriptor
+		DocumentDescriptor desc = docMgr.newDescriptor(template.getDirectory());
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		
+		ObjectNode fragmentNode = mapper.createObjectNode();
+		fragmentNode = mapper.createObjectNode();
+		fragmentNode.put("insertedKey", 9);
+		String fragment = mapper.writeValueAsString(fragmentNode);
+		
+		patchBldr.insertFragment("$.employees", Position.LAST_CHILD, fragment);
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		Transaction t = client.openTransaction("Tranc");
+		docMgr.patch(desc, patchHandle,t);
+			t.commit();
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("After"+content);
+		
+		assertTrue("fragment is not inserted", content.contains("{\"insertedKey\":9}]"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testPartialUpdateCardinality() throws IOException
+	{	
+		System.out.println("Running testPartialUpdateCardinality");
+		
+		String filename = "constraint1.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		writeDocumentUsingInputStreamHandle(client, filename, "/partial-update/", "XML");
+		
+		String docId = "/partial-update/constraint1.xml";
+		
+		//Creating Manager
+		XMLDocumentManager xmlDocMgr = client.newXMLDocumentManager();
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+				
+		//Inserting Node
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root", Position.LAST_CHILD, Cardinality.ONE, "2013-03-21");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		String contentBefore = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(" Content after Updating with Cardinality.ONE : "+ contentBefore );
+		assertTrue("Insertion Failed ", contentBefore.contains(""));
+		//Updating again
+		DocumentPatchBuilder xmlPatchBldr = xmlDocMgr.newPatchBuilder();
+		DocumentPatchHandle xmlPatchForNode = xmlPatchBldr.insertFragment("/root/id", Position.BEFORE , Cardinality.ONE_OR_MORE, "1989-04-06").build();
+		xmlDocMgr.patch(docId, xmlPatchForNode);
+		String contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("Content after Updating with Cardinality.ONE_OR_MORE" + contentAfter);
+		assertTrue("Insertion Failed ", contentAfter.contains("1989-04-06"));
+		//Updating again
+		DocumentPatchBuilder xmlPatchBldr1 = xmlDocMgr.newPatchBuilder();
+		DocumentPatchHandle xmlPatchForNode1 = xmlPatchBldr1.insertFragment("/root/id", Position.AFTER , Cardinality.ZERO_OR_ONE, "2013-07-29").build();
+		xmlDocMgr.patch(docId, xmlPatchForNode1);
+		contentAfter = xmlDocMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println("Content after Updating with Cardinality.ZERO_OR_ONE" + contentAfter);
+		assertTrue("Insertion Failed ", contentAfter.contains("2013-07-29"));
+		
+		// release client
+		client.release();		
+	}	
+@AfterClass	
+public static void tearDown() throws Exception
+	{
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestPatchCardinality.java b/test-complete/src/test/java/com/marklogic/javaclient/TestPatchCardinality.java
new file mode 100644
index 000000000..54182bb50
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestPatchCardinality.java
@@ -0,0 +1,410 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentManager.Metadata;
+import com.marklogic.client.document.DocumentMetadataPatchBuilder.Cardinality;
+import com.marklogic.client.document.DocumentPatchBuilder;
+import com.marklogic.client.document.DocumentPatchBuilder.Position;
+import com.marklogic.client.document.DocumentMetadataPatchBuilder;
+import com.marklogic.client.document.JSONDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.io.marker.DocumentPatchHandle;
+import org.junit.*;
+
+public class TestPatchCardinality extends BasicJavaClientREST {
+
+	private static String dbName = "TestPatchCardinalityDB";
+	private static String [] fNames = {"TestPatchCardinalityDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testOneCardinalityNegative() throws IOException
+	{	
+		System.out.println("Running testOneCardinalityNegative");
+		
+		String[] filenames = {"cardinal1.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal1.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ONE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		
+		String exception = "";
+		try
+		{
+			docMgr.patch(docId, patchHandle);
+		}
+		catch (Exception e)
+		{
+			System.out.println(e.getMessage());
+			exception = e.getMessage();
+		}
+		
+		String expectedException = "Local message: write failed: Bad Request. Server Message: RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request:  reason: invalid content patch operations for uri /cardinal/cardinal1.xml: invalid cardinality of 5 nodes for: /root/foo";
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+				
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testOneCardinalityPositve() throws IOException
+	{	
+		System.out.println("Running testOneCardinalityPositive");
+		
+		String[] filenames = {"cardinal2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal2.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ONE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("added"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testOneOrMoreCardinalityPositve() throws IOException
+	{	
+		System.out.println("Running testOneOrMoreCardinalityPositive");
+		
+		String[] filenames = {"cardinal1.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal1.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ONE_OR_MORE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("oneadded"));
+		assertTrue("fragment is not inserted", content.contains("twoadded"));
+		assertTrue("fragment is not inserted", content.contains("threeadded"));
+		assertTrue("fragment is not inserted", content.contains("fouradded"));
+		assertTrue("fragment is not inserted", content.contains("fiveadded"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testOneOrMoreCardinalityNegative() throws IOException
+	{	
+		System.out.println("Running testOneOrMoreCardinalityNegative");
+		
+		String[] filenames = {"cardinal3.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal3.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ONE_OR_MORE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+
+		String exception = "";
+		try
+		{
+			docMgr.patch(docId, patchHandle);
+		}
+		catch (Exception e)
+		{
+			System.out.println(e.getMessage());
+			exception = e.getMessage();
+		}
+		
+		String expectedException = "Local message: write failed: Bad Request. Server Message: RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request:  reason: invalid content patch operations for uri /cardinal/cardinal3.xml: invalid cardinality of 0 nodes for: /root/foo";
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testZeroOrOneCardinalityNegative() throws IOException
+	{	
+		System.out.println("Running testZeroOrOneCardinalityNegative");
+		
+		String[] filenames = {"cardinal1.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal1.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ZERO_OR_ONE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+
+		String exception = "";
+		try
+		{
+			docMgr.patch(docId, patchHandle);
+		}
+		catch (Exception e)
+		{
+			System.out.println(e.getMessage());
+			exception = e.getMessage();
+		}
+		
+		String expectedException = "Local message: write failed: Bad Request. Server Message: RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request:  reason: invalid content patch operations for uri /cardinal/cardinal1.xml: invalid cardinality of 5 nodes for: /root/foo";
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testZeroOrOneCardinalityPositive() throws IOException
+	{	
+		System.out.println("Running testZeroOrOneCardinalityPositive");
+		
+		String[] filenames = {"cardinal2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal2.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ZERO_OR_ONE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("oneadded"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testZeroOrOneCardinalityPositiveWithZero() throws IOException
+	{	
+		System.out.println("Running testZeroOrOneCardinalityPositiveWithZero");
+		
+		String[] filenames = {"cardinal3.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal3.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ZERO_OR_ONE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertFalse("fragment is inserted", content.contains("oneadded"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testZeroOrMoreCardinality() throws IOException
+	{	
+		System.out.println("Running testZeroOrMoreCardinality");
+		
+		String[] filenames = {"cardinal1.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+		}
+		
+		String docId = "/cardinal/cardinal1.xml";
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+		patchBldr.insertFragment("/root/foo", Position.AFTER, Cardinality.ZERO_OR_MORE, "added");
+		DocumentPatchHandle patchHandle = patchBldr.build();
+		docMgr.patch(docId, patchHandle);
+		
+		String content = docMgr.read(docId, new StringHandle()).get();
+		
+		System.out.println(content);
+		
+		assertTrue("fragment is not inserted", content.contains("oneadded"));
+		assertTrue("fragment is not inserted", content.contains("twoadded"));
+		assertTrue("fragment is not inserted", content.contains("threeadded"));
+		assertTrue("fragment is not inserted", content.contains("fouradded"));
+		assertTrue("fragment is not inserted", content.contains("fiveadded"));
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug23843() throws IOException
+	{	
+		System.out.println("Running testBug23843");
+		
+		String[] filenames = {"cardinal1.xml","cardinal4.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/cardinal/", "XML");
+			
+			String docId = "";
+			
+			XMLDocumentManager docMgr = client.newXMLDocumentManager();
+			DocumentMetadataHandle readMetadataHandle = new DocumentMetadataHandle();
+			
+			DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder();
+			if (filename == "cardinal1.xml"){
+				patchBldr.insertFragment("/root", Position.LAST_CHILD, Cardinality.ONE, "added");
+			}
+			else if (filename == "cardinal4.xml") {
+				patchBldr.insertFragment("/root", Position.LAST_CHILD, "added");
+			}
+			DocumentPatchHandle patchHandle = patchBldr.build();
+			String RawPatch = patchHandle.toString();
+			System.out.println("Before"+RawPatch);
+			
+			String exception = "";
+			if (filename == "cardinal1.xml"){
+				try
+				{	docId= "/cardinal/cardinal1.xml";
+					docMgr.patch(docId, patchHandle);
+					System.out.println("After"+docMgr.readMetadata(docId, new DocumentMetadataHandle()).toString());
+					assertEquals("rest-readerreadrest-writerupdate0", docMgr.readMetadata(docId, new DocumentMetadataHandle()).toString());
+				}
+				catch (Exception e)
+				{
+					System.out.println(e.getMessage());
+					exception = e.getMessage();
+				}
+			}
+			else if (filename == "cardinal4.xml") {
+				try
+				{	
+					docId = "/cardinal/cardinal4.xml";
+					docMgr.clearMetadataCategories();
+					docMgr.patch(docId, new StringHandle(patchHandle.toString()));
+					docMgr.setMetadataCategories(Metadata.ALL);
+					System.out.println("After"+docMgr.readMetadata(docId, new DocumentMetadataHandle()).toString());
+					assertEquals("", "rest-readerreadrest-writerupdate0", docMgr.readMetadata(docId, new DocumentMetadataHandle()).toString());
+				}
+				catch (Exception e)
+				{
+					System.out.println(e.getMessage());
+					exception = e.getMessage();
+				}
+			}
+
+			String actual = docMgr.read(docId, new StringHandle()).get();
+			
+			System.out.println("Actual : "+actual);
+		}
+		
+		// release client
+		client.release();		
+	}
+@AfterClass
+public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryByExample.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryByExample.java
new file mode 100644
index 000000000..6e52f3bc7
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryByExample.java
@@ -0,0 +1,470 @@
+package com.marklogic.javaclient;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.FailedRequestException;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.document.DocumentMetadataPatchBuilder;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+import com.marklogic.client.query.RawQueryByExampleDefinition;
+import com.sun.jersey.api.client.ClientHandlerException;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.junit.*;
+public class TestQueryByExample extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryByExampleDB";
+	private static String [] fNames = {"TestQueryByExampleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test
+	public void testQueryByExampleXML() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXML");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.xml");
+        
+        String qbeQuery = convertFileToString(file);
+        StringHandle qbeHandle = new StringHandle(qbeQuery);
+        qbeHandle.setFormat(Format.XML);
+        
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(qbeHandle);
+        
+        Document resultDoc = queryMgr.search(qbyex, new DOMHandle()).get();
+        
+        System.out.println("XML Result"+convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleXMLnew() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXML");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.xml");
+        
+        String qbeQuery = convertFileToString(file);
+        StringHandle qbeHandle = new StringHandle(qbeQuery);
+        qbeHandle.setFormat(Format.XML);
+        
+        
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(qbeHandle);
+        Document resultDoc = queryMgr.search(qbyex, new DOMHandle()).get();
+        
+        System.out.println("XML Result"+convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleJSON() throws IOException
+	{	
+		System.out.println("Running testQueryByExampleJSON");
+		
+		String[] filenames = {"constraint1.json", "constraint2.json", "constraint3.json", "constraint4.json", "constraint5.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "JSON");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.json");
+        
+        String qbeQuery = convertFileToString(file);
+        StringHandle qbeHandle = new StringHandle(qbeQuery);
+        qbeHandle.setFormat(Format.JSON);
+        
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(qbeHandle);
+        
+        String resultDoc = queryMgr.search(qbyex, new StringHandle()).get();
+        
+        System.out.println(resultDoc);
+
+        assertTrue("total result is not correct", resultDoc.contains("\"total\":1"));
+        assertTrue("doc returned is not correct", resultDoc.contains("{\"snippet-format\":\"snippet\",\"total\":1,\"start\":1,\"page-length\":10,\"results\":[{\"index\":1,\"uri\":\"/qbe/constraint1.json\",\"path\":\"fn:doc(\\\"/qbe/constraint1.json\\\")\",\"score\":28672,\"confidence\":0.6951694,\"fitness\":0.6951694,\"href\":\"/v1/documents?uri=%2Fqbe%2Fconstraint1.json\",\"mimetype\":\"application/json\",\"format\":\"json\",\"matches\":[{\"path\":\"fn:doc(\\\"/qbe/constraint1.json\\\")/*:json/*:root/*:id\",\"match-text\":[{\"highlight\":11}]}],\"metadata\":[{\"title\":\"Vannevar Bush\",\"metadata-type\":\"element\"},{\"id\":11,\"metadata-type\":\"element\"},{\"p\":\"Vannevar Bush wrote an article for The Atlantic Monthly\",\"metadata-type\":\"element\"},{\"popularity\":5,\"metadata-type\":\"element\"}]}]"));
+        
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug22179() throws IOException
+	{	
+		System.out.println("Running testBug22179");
+		
+		String[] filenames = {"constraint1.json", "constraint2.json", "constraint3.json", "constraint4.json", "constraint5.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "JSON");
+		}
+		
+		  ServerConfigurationManager confMgr = client.newServerConfigManager();
+		  confMgr.setQueryValidation(true);
+		
+		  String combinedCriteria ="{\"search\":{\"options\":{\"constraint\":[{\"name\":\"para\", \"word\":{\"term-option\":[\"case-insensitive\"], \"field\":{\"name\":\"para\"}}},{\"name\":\"id\", \"value\":{\"element\":{\"ns\":\"\", \"name\":\"id\"}}}], \"return-metrics\":false, \"debug\":true, \"return-qtext\":false, \"transform-results\":{\"apply\":\"snippet\"}}, \"query\":{\"queries\":[{\"or-query\":{\"queries\":[{\"and-query\":{\"queries\":[{\"word-constraint-query\":{\"text\":[\"Bush\"], \"constraint-name\":\"para\"}},{\"not-query\":{\"word-constraint-query\":{\"text\":[\"memex\"], \"constraint-name\":\"para\"}}}]}},{\"and-query\":{\"queries\":[{\"value-constraint-query\":{\"text\":[\"0026\"], \"constraint-name\":\"id\"}},{\"term-query\":{\"text\":[\"memex\"]}}]}}]}}]}}}";
+		  QueryManager queryMgr = client.newQueryManager();
+		   
+		  StringHandle combinedHandle = new StringHandle(combinedCriteria).withFormat(Format.JSON);
+		  RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(combinedHandle);
+		  String output = queryMgr.search(querydef, new StringHandle()).get();
+		  System.out.println(output);
+		  assertTrue(output.contains("(cts:search(fn:collection(), cts:or-query((cts:and-query((cts:field-word-query"));
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleXMLPayload() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXMLPayload");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.xml");
+        FileHandle fileHandle = new FileHandle(file);
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition rw = queryMgr.newRawQueryByExampleDefinition(fileHandle.withFormat(Format.XML));
+        SearchHandle results = queryMgr.search(rw, new SearchHandle());
+        
+        for (MatchDocumentSummary result : results.getMatchResults()) 
+		{
+			System.out.println(result.getUri()+ ": Uri");
+			assertEquals("Wrong Document Searched",result.getUri() , "/qbe/constraint1.xml");
+		} 
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleJSONPayload() throws IOException, Exception
+	{	
+		System.out.println("Running testQueryByExampleJSONPayload");
+		
+		String[] filenames = {"constraint1.json", "constraint2.json", "constraint3.json", "constraint4.json", "constraint5.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "JSON");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.json");
+        FileHandle fileHandle = new FileHandle(file);
+
+        QueryManager queryMgr = client.newQueryManager();
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(fileHandle.withFormat(Format.JSON));
+        String resultDoc = queryMgr.search(qbyex, new StringHandle()).get();
+        System.out.println(resultDoc);
+        assertTrue("Result is not proper", resultDoc.contains("/qbe/constraint1.json"));
+        
+        
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleXMLPermission() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXMLPermission");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+		}
+		
+		// get the combined query
+		try{
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe2.xml");
+     
+        FileHandle fileHandle = new FileHandle(file);
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition rw = queryMgr.newRawQueryByExampleDefinition(fileHandle.withFormat(Format.XML));
+        SearchHandle results = queryMgr.search(rw, new SearchHandle());
+        
+        for (MatchDocumentSummary result : results.getMatchResults()) 
+		{
+			System.out.println(result.getUri()+ ": Uri");
+			assertEquals("Wrong Document Searched",result.getUri() , "/qbe/constraint1.xml");
+		} 
+		}catch(ClientHandlerException e){
+			System.out.println("Negative Test Passed of executing nonreadable file");			
+		}
+		// release client
+		client.release();		
+		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleWrongXML() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXMLPayload");
+		
+		String filename = "WrongFormat.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		try{
+			// write docs
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+			
+			
+			// get the combined query
+        	File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.xml");
+        	FileHandle fileHandle = new FileHandle(file);
+        	QueryManager queryMgr = client.newQueryManager();
+        	
+        	RawQueryByExampleDefinition rw = queryMgr.newRawQueryByExampleDefinition(fileHandle.withFormat(Format.XML));
+        	SearchHandle results = queryMgr.search(rw, new SearchHandle());
+        	
+        	for (MatchDocumentSummary result : results.getMatchResults()) 
+			{
+				System.out.println(result.getUri()+ ": Uri");
+			//	assertEquals("Wrong Document Searched",result.getUri() , "/qbe/constraint1.xml");
+			} 
+		}catch(FailedRequestException e){
+				System.out.println("Negative test passed as XML with invalid structure gave FailedRequestException ");
+			}
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleWrongJSON() throws IOException
+	{	
+		System.out.println("Running testQueryByExampleJSON");
+		
+		String filename = "WrongFormat.json";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		try{	
+		// write docs
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "JSON");
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.json");
+        
+        String qbeQuery = convertFileToString(file);
+        StringHandle qbeHandle = new StringHandle(qbeQuery);
+        qbeHandle.setFormat(Format.JSON);
+        
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(qbeHandle);
+        
+        String resultDoc = queryMgr.search(qbyex, new StringHandle()).get();
+        
+        System.out.println(resultDoc);
+
+        assertTrue("total result is not correct", resultDoc.contains("\"total\":1"));
+        assertTrue("doc returned is not correct", resultDoc.contains("\"metadata\":[{\"title\":\"Vannevar Bush\"},{\"id\":11},{\"p\":\"Vannevar Bush wrote an article for The Atlantic Monthly\"},{\"popularity\":5}]"));
+		}catch(FailedRequestException e){
+			System.out.println("Negative test passed as JSON with invalid structure gave FailedRequestException ");
+		}
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleXMLWrongQuery() throws IOException, TransformerException, XpathException
+	{	
+		System.out.println("Running testQueryByExampleXMLWrongQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.xml");
+        FileHandle fileHandle = new FileHandle(file);
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition rw = queryMgr.newRawQueryByExampleDefinition(fileHandle.withFormat(Format.XML));
+        SearchHandle results = queryMgr.search(rw, new SearchHandle());
+        
+        for (MatchDocumentSummary result : results.getMatchResults()) 
+		{
+			System.out.println(result.getUri()+ ": Uri");
+			assertEquals("Wrong Document Searched",result.getUri() , "/qbe/constraint1.xml");
+		} 
+        try{
+        File wrongFile = new File("src/junit/com/marklogic/javaclient/qbe/WrongQbe.xml");
+        FileHandle wrongFileHandle = new FileHandle(wrongFile);
+        QueryManager newQueryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition newRw = newQueryMgr.newRawQueryByExampleDefinition(wrongFileHandle.withFormat(Format.XML));
+        SearchHandle newResults = queryMgr.search(newRw, new SearchHandle());
+        
+        for (MatchDocumentSummary result : newResults.getMatchResults()) 
+		{
+			System.out.println(result.getUri()+ ": Uri");
+			assertEquals("Wrong Document Searched",result.getUri() , "/qbe/constraint1.xml");
+		} 
+        }catch(FailedRequestException e){
+        	System.out.println("Negative test passed as Query with improper Xml format gave FailedRequestException ");	
+        }
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testQueryByExampleJSONWrongQuery() throws IOException
+	{	
+		System.out.println("Running testQueryByExampleJSONWrongQuery");
+		
+		String[] filenames = {"constraint1.json", "constraint2.json", "constraint3.json", "constraint4.json", "constraint5.json"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/qbe/", "JSON");
+		}
+		
+		// get the Correct query
+        File file = new File("src/junit/com/marklogic/javaclient/qbe/qbe1.json");
+        
+        String qbeQuery = convertFileToString(file);
+        StringHandle qbeHandle = new StringHandle(qbeQuery);
+        qbeHandle.setFormat(Format.JSON);
+        
+        QueryManager queryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition qbyex = queryMgr.newRawQueryByExampleDefinition(qbeHandle);
+        
+        String resultDoc = queryMgr.search(qbyex, new StringHandle()).get();
+        
+        System.out.println("Result of Correct Query"+ resultDoc);
+
+        //assertTrue("total result is not correct", resultDoc.contains("\"total\":1"));
+      //  assertTrue("doc returned is not correct", resultDoc.contains("\"metadata\":[{\"title\":\"Vannevar Bush\"},{\"id\":11},{\"p\":\"Vannevar Bush wrote an article for The Atlantic Monthly\"},{\"popularity\":5}]"));
+        
+     // get the query with Wrong Format
+        
+        File wrongFile = new File("src/junit/com/marklogic/javaclient/qbe/WrongQbe.json");
+        
+        String wrongQbeQuery = convertFileToString(wrongFile);
+        StringHandle newQbeHandle = new StringHandle(wrongQbeQuery);
+        newQbeHandle.setFormat(Format.JSON);
+        
+        QueryManager newQueryMgr = client.newQueryManager();
+        
+        RawQueryByExampleDefinition newQbyex = newQueryMgr.newRawQueryByExampleDefinition(newQbeHandle);
+        try{
+        String newResultDoc = newQueryMgr.search(newQbyex, new StringHandle()).get();
+        
+        System.out.println("Result of Wrong Query"+newResultDoc);
+
+        assertTrue("total result is not correct", resultDoc.contains("\"total\":1"));
+        assertTrue("doc returned is not correct", resultDoc.contains("\"metadata\":[{\"title\":\"Vannevar Bush\"},{\"id\":11},{\"p\":\"Vannevar Bush wrote an article for The Atlantic Monthly\"},{\"popularity\":5}]"));
+        }catch(FailedRequestException e){
+        	System.out.println("Negative test passed as Query with improper JSON format gave FailedRequestException ");
+        }
+		// release client
+		client.release();		
+	}
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilder.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilder.java
new file mode 100644
index 000000000..e0e0beb73
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilder.java
@@ -0,0 +1,777 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.admin.config.QueryOptions.Facets;
+import com.marklogic.client.admin.config.QueryOptions.FragmentScope;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilder extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderDB";
+	private static String [] fNames = {"TestQueryOptionBuilderDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testValueConstraintWildcard() throws FileNotFoundException, XpathException
+	{	
+		System.out.println("Running testValueConstraintWildcard");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/value-constraint-query-builder/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConstraints( builder.constraint("id", 
+                builder.value(builder.elementTermIndex(new QName("id")))))
+                .withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false)
+                		.debug(true))
+                .withTransformResults(builder.rawResults());
+               
+        // write query options
+        optionsMgr.writeOptions("ValueConstraintWildcard", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("ValueConstraintWildcard", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("ValueConstraintWildcard");
+		querydef.setCriteria("id:00*2 OR id:0??6");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testWordConstraintNormalWordQuery() throws FileNotFoundException, XpathException
+	{	
+		System.out.println("Running testWordConstraintNormalWordQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/word-constraint-query-builder/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConstraints(builder.constraint("intitle", 
+                        			builder.word(builder.elementTermIndex(new QName("title")))),
+                        		builder.constraint("inprice",
+                        			builder.word(builder.elementAttributeTermIndex(
+                        					new QName("http://cloudbank.com", "price"),
+                        					new QName("amt")))))
+                .withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false)
+                		.debug(true))
+                .withTransformResults(builder.rawResults());
+               
+		
+        // write query options
+        optionsMgr.writeOptions("WordConstraintNormalWordQuery", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("WordConstraintNormalWordQuery", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("WordConstraintNormalWordQuery");
+		querydef.setCriteria("Memex  OR inprice:.12");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The memex", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("0.12", "string(//*[local-name()='result'][1]//@*[local-name()='amt'])", resultDoc);
+		assertXpathEvaluatesTo("123.45", "string(//*[local-name()='result'][2]//@*[local-name()='amt'])", resultDoc);
+	    
+		String expectedSearchReport = "(cts:search(fn:collection(), cts:or-query((cts:word-query(\"Memex\", (\"lang=en\"), 1), cts:element-attribute-word-query(fn:QName(\"http://cloudbank.com\", \"price\"), fn:QName(\"\", \"amt\"), \".12\", (\"lang=en\"), 1))), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testAllConstraintsWithStringSearch() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testAllConstraintsWithStringSearch");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options		
+	
+        handle.
+                withConstraints(
+                		builder.constraint("id", 
+                				builder.value(builder.elementTermIndex(new QName("id")))),
+                		builder.constraint("date",
+                				builder.range(
+                						builder.elementRangeIndex(new QName("http://purl.org/dc/elements/1.1/", "date"), 
+                								builder.rangeType("xs:date")))),                                
+                		builder.constraint("coll", 
+                				builder.collection("http://test.com/", Facets.FACETED)),
+                		builder.constraint("para",
+                				builder.word(builder.fieldTermIndex("para"), null, null, "case-insensitive")),
+                		builder.constraint("intitle",
+                				builder.word(builder.elementTermIndex(new QName("title")))),
+                		builder.constraint("price",
+                				builder.range(builder.elementAttributeRangeIndex(new QName("http://cloudbank.com", "price"),
+                						new QName("amt"), builder.rangeType("xs:decimal")),
+                						Facets.UNFACETED,
+                						null,
+                						builder.buckets(
+                								builder.bucket("high", "High", "120", null),
+                								builder.bucket("medium", "Medium", "3", "14"),
+                								builder.bucket("low", "Low", "0", "2")))),
+                		builder.constraint("pop",
+                				builder.range(builder.elementRangeIndex(new QName("popularity"),
+                						builder.rangeType("xs:int")),
+                						Facets.FACETED,
+                						null,
+                						builder.buckets(builder.bucket("high", "High", "5", null),
+                                      builder.bucket("medium", "Medium", "3", "5"),
+                                      builder.bucket("low", "Low", "1", "3")))))
+                 .withConfiguration(builder.configure()
+                		 .returnMetrics(false)
+                		 .returnQtext(false)
+                		 .debug(true))
+                 .withTransformResults(builder.rawResults());
+                		 
+                		
+        // write query options
+        optionsMgr.writeOptions("AllConstraintsWithStringSearch", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("AllConstraintsWithStringSearch", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("AllConstraintsWithStringSearch");
+		querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex AND (pop:high OR pop:medium) AND price:low AND id:**11 AND date:2005-01-01 AND (para:Bush AND -para:memex)");
+				
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testAllConstraintsWithStructuredSearch() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testAllConstraintsWithStructuredSearch");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options		
+	
+        handle.
+        withConstraints(
+        		builder.constraint("id", 
+        				builder.value(builder.elementTermIndex(new QName("id")))),
+        		builder.constraint("date",
+        				builder.range(
+        						builder.elementRangeIndex(new QName("http://purl.org/dc/elements/1.1/", "date"), 
+        								builder.rangeType("xs:date")))),                                
+        		builder.constraint("coll", 
+        				builder.collection("http://test.com/", Facets.FACETED)),
+        		builder.constraint("para",
+        				builder.word(builder.fieldTermIndex("para"), null, null, "case-insensitive")),
+        		builder.constraint("intitle",
+        				builder.word(builder.elementTermIndex(new QName("title")))),
+        		builder.constraint("price",
+        				builder.range(builder.elementAttributeRangeIndex(new QName("http://cloudbank.com", "price"),
+        						new QName("amt"), builder.rangeType("xs:decimal")),
+        						Facets.UNFACETED,
+        						null,
+        						builder.buckets(
+        								builder.bucket("high", "High", "120", null),
+        								builder.bucket("medium", "Medium", "3", "14"),
+        								builder.bucket("low", "Low", "0", "2")))),
+        		builder.constraint("pop",
+        				builder.range(builder.elementRangeIndex(new QName("popularity"),
+        						builder.rangeType("xs:int")),
+        						Facets.FACETED,
+        						null,
+        						builder.buckets(builder.bucket("high", "High", "5", null),
+                              builder.bucket("medium", "Medium", "3", "5"),
+                              builder.bucket("low", "Low", "1", "3")))))
+         .withConfiguration(builder.configure()
+        		 .returnMetrics(false)
+        		 .returnQtext(false)
+        		 .debug(true))
+         .withTransformResults(builder.rawResults());
+       
+        
+        // write query options
+        optionsMgr.writeOptions("AllConstraintsWithStructuredSearch", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("AllConstraintsWithStructuredSearch", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("AllConstraintsWithStructuredSearch");
+		StructuredQueryDefinition query1 = qb.and(qb.collectionConstraint("coll", "set1"), qb.collectionConstraint("coll", "set5"));
+		StructuredQueryDefinition query2 = qb.not(qb.wordConstraint("intitle", "memex"));
+		StructuredQueryDefinition query3 = qb.valueConstraint("id", "**11");
+		StructuredQueryDefinition query4 = qb.rangeConstraint("date", StructuredQueryBuilder.Operator.EQ, "2005-01-01");
+		StructuredQueryDefinition query5 = qb.and(qb.wordConstraint("para", "Bush"), qb.not(qb.wordConstraint("para", "memex")));
+		StructuredQueryDefinition query6 = qb.rangeConstraint("price", StructuredQueryBuilder.Operator.EQ, "low");
+		StructuredQueryDefinition query7 = qb.or(qb.rangeConstraint("pop", StructuredQueryBuilder.Operator.EQ, "high"), qb.rangeConstraint("pop", StructuredQueryBuilder.Operator.EQ, "medium"));
+		StructuredQueryDefinition queryFinal = qb.and(query1, query2, query3, query4, query5, query6, query7);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testExtractMetadataWithStructuredSearch() throws XpathException, TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testExtractMetadataWithStructuredSearch");
+		
+		String filename = "xml-original.xml";
+		String uri = "/extract-metadata/";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		ServerConfigurationManager scMgr = client.newServerConfigManager();
+		scMgr.setServerRequestLogging(true);
+		scMgr.writeConfiguration();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+	    // write the doc
+	    writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+		String docId = uri + filename;
+	    	    
+	    // write metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle);
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure().fragmentScope(FragmentScope.PROPERTIES));
+        handle.withExtractMetadata(builder.extractMetadata(builder.elementValue(new QName("", "Author")), builder.elementValue(new QName("", "AppName"))));
+        //handle.withExtractMetadata(builder.extractMetadata(builder.elementValue(new QName("", "Author")), builder.constraintValue("appname")));
+        handle.withConstraints(builder.constraint("appname", builder.word(builder.elementTermIndex(new QName("AppName")))));
+        
+        // write query options
+        optionsMgr.writeOptions("ExtractMetadataWithStructuredSearch", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("ExtractMetadataWithStructuredSearch", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+        
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("ExtractMetadataWithStructuredSearch");
+		StructuredQueryDefinition queryTerm1 = qb.term("MarkLogic");
+		StructuredQueryDefinition queryTerm2 = qb.term("Microsoft");
+		//StructuredQueryDefinition queryWord = qb.wordConstraint("appname", "Microsoft");
+		StructuredQueryDefinition queryFinal = qb.and(queryTerm1, queryTerm2);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='Author'])", resultDoc);
+		assertXpathEvaluatesTo("Microsoft Office Word", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='AppName'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+	
+	// See bug 18361
+	/*public void testExtractMetadataWithStructuredSearchAndConstraint() throws XpathException, TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testExtractMetadataWithStructuredSearchAndConstraint");
+		
+		String filename = "xml-original.xml";
+		String uri = "/extract-metadata/";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		ServerConfigurationManager scMgr = client.newServerConfigManager();
+		scMgr.setServerRequestLogging(true);
+		scMgr.writeConfiguration();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+	    // write the doc
+	    writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+		String docId = uri + filename;
+	    	    
+	    // write metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle);
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure().fragmentScope(FragmentScope.PROPERTIES));
+        handle.withExtractMetadata(builder.extractMetadata(builder.elementValue(new QName("", "Author")), builder.constraintValue("appname")));
+        handle.withConstraints(builder.constraint("appname", builder.word(builder.elementTermIndex(new QName("AppName")))));
+        
+        // write query options
+        optionsMgr.writeOptions("ExtractMetadataWithStructuredSearchAndConstraint", handle);
+        
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("ExtractMetadataWithStructuredSearchAndConstraint");
+		StructuredQueryDefinition queryTerm = qb.term("MarkLogic");
+		StructuredQueryDefinition queryWord = qb.wordConstraint("appname", "Microsoft");
+		StructuredQueryDefinition queryFinal = qb.and(queryTerm, queryWord);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		//assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='Author'])", resultDoc);
+		//assertXpathEvaluatesTo("Microsoft Office Word", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='AppName'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}*/
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testExtractMetadataWithStructuredSearchAndRangeConstraint() throws XpathException, TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testExtractMetadataWithStructuredSearchAndRangeConstraint");
+		
+		String filename = "xml-original.xml";
+		String uri = "/extract-metadata/";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		ServerConfigurationManager scMgr = client.newServerConfigManager();
+		scMgr.setServerRequestLogging(true);
+		scMgr.writeConfiguration();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+	    // write the doc
+	    writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+		String docId = uri + filename;
+	    	    
+	    // write metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle);
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure().fragmentScope(FragmentScope.PROPERTIES));
+        handle.withExtractMetadata(builder.extractMetadata(builder.elementValue(new QName("", "Author")), builder.constraintValue("pop")));
+        //handle.withConstraints(builder.constraint("appname", builder.word(builder.elementTermIndex(new QName("AppName")))));
+        handle.withConstraints(builder.constraint("pop",
+				builder.range(builder.elementRangeIndex(new QName("popularity"),
+						builder.rangeType("xs:int")),
+						Facets.FACETED,
+						null,
+						builder.buckets(builder.bucket("high", "High", "5", null),
+                      builder.bucket("medium", "Medium", "3", "5"),
+                      builder.bucket("low", "Low", "1", "3")))));
+        
+        // write query options
+        optionsMgr.writeOptions("ExtractMetadataWithStructuredSearchAndRangeConstraint", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("ExtractMetadataWithStructuredSearchAndRangeConstraint", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+        
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("ExtractMetadataWithStructuredSearchAndRangeConstraint");
+		StructuredQueryDefinition queryFinal = qb.rangeConstraint("pop", StructuredQueryBuilder.Operator.EQ, "high");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='Author'])", resultDoc);
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='constraint-meta'])", resultDoc);
+		//assertXpathEvaluatesTo("Microsoft Office Word", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='AppName'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testDocumentLevelMetadata() throws XpathException, TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testDocumentLevelMetadata");
+		
+		String filename = "xml-original.xml";
+		String uri = "/extract-metadata/";
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		ServerConfigurationManager scMgr = client.newServerConfigManager();
+		scMgr.setServerRequestLogging(true);
+		scMgr.writeConfiguration();
+		
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+		
+	    // write the doc
+	    writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+		
+		// create doc id
+		String docId = uri + filename;
+	    	    
+	    // write metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle);
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure().fragmentScope(FragmentScope.DOCUMENTS));
+        handle.withExtractMetadata(builder.extractMetadata(builder.elementValue(new QName("", "Author")), builder.constraintValue("pop"), builder.elementValue(new QName("", "name"))));
+        //handle.withConstraints(builder.constraint("appname", builder.word(builder.elementTermIndex(new QName("AppName")))));
+        handle.withConstraints(builder.constraint("pop",
+				builder.range(builder.elementRangeIndex(new QName("popularity"),
+						builder.rangeType("xs:int")),
+						Facets.FACETED,
+						null,
+						builder.buckets(builder.bucket("high", "High", "5", null),
+                      builder.bucket("medium", "Medium", "3", "5"),
+                      builder.bucket("low", "Low", "1", "3")))));
+        
+        // write query options
+        optionsMgr.writeOptions("DocumentLevelMetadata", handle);
+        
+        // read query option
+     	StringHandle readHandle = new StringHandle();
+     	readHandle.setFormat(Format.XML);
+     	optionsMgr.readOptions("DocumentLevelMetadata", readHandle);
+     	String output = readHandle.get();
+     	System.out.println(output);
+        
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("DocumentLevelMetadata");
+		StructuredQueryDefinition queryFinal = qb.term("noodle");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("noodle", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='name'])", resultDoc);
+		//assertXpathEvaluatesTo("5", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='constraint-meta'])", resultDoc);
+		//assertXpathEvaluatesTo("Microsoft Office Word", "string(//*[local-name()='result']//*[local-name()='metadata']/*[local-name()='AppName'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderGrammar.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderGrammar.java
new file mode 100644
index 000000000..abe460ba6
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderGrammar.java
@@ -0,0 +1,335 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import java.io.FileNotFoundException;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptions.QueryGrammar.QueryJoiner.JoinerApply;
+import com.marklogic.client.admin.config.QueryOptions.QueryGrammar.Tokenize;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.impl.Utilities;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilderGrammar extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderGrammarDB";
+	private static String [] fNames = {"TestQueryOptionBuilderGrammarDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+@BeforeClass
+	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testGrammarOperatorQuotation() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testGrammarOperatorQuotation");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/gramar-op-quote/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withGrammar(builder.grammar(builder.starters(builder.starterGrouping("(", 30, ")"),
+            		                                        builder.starterPrefix("-", 40, "cts:not-query")),	
+            		                       builder.joiners(builder.joiner("OR", 20, JoinerApply.INFIX, "cts:or-query", Tokenize.WORD),
+            		                                       builder.joiner("AND", 30, JoinerApply.INFIX, "cts:and-query", Tokenize.WORD),
+            		                                       builder.joiner(":", 50, JoinerApply.CONSTRAINT)),
+            		                       "\"",
+            		                       Utilities.domElement("")));
+             
+        // write query options
+        optionsMgr.writeOptions("GrammarOperatorQuotation", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("GrammarOperatorQuotation", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("GrammarOperatorQuotation");
+	    querydef.setCriteria("1945 OR \"Atlantic Monthly\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0113", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testGrammarTwoWordsSpace() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testGrammarTwoWordsSpace");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/gramar-two-words-space/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withGrammar(builder.grammar(builder.starters(builder.starterGrouping("(", 30, ")"),
+            		                                        builder.starterPrefix("-", 40, "cts:not-query")),	
+            		                       builder.joiners(builder.joiner("OR", 20, JoinerApply.INFIX, "cts:or-query", Tokenize.WORD),
+            		                                       builder.joiner("AND", 30, JoinerApply.INFIX, "cts:and-query", Tokenize.WORD),
+            		                                       builder.joiner(":", 50, JoinerApply.CONSTRAINT)),
+            		                       "\"",
+            		                       Utilities.domElement("")));
+             
+        // write query options
+        optionsMgr.writeOptions("GrammarTwoWordsSpace", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("GrammarTwoWordsSpace", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("GrammarTwoWordsSpace");
+	    querydef.setCriteria("\"Atlantic Monthly\" \"Bush\"");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testGrammarPrecedenceAndNegate() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testGrammarPrecedenceAndNegate");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/gramar-two-words-space/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withGrammar(builder.grammar(builder.starters(builder.starterGrouping("(", 30, ")"),
+            		                                        builder.starterPrefix("-", 40, "cts:not-query")),	
+            		                       builder.joiners(builder.joiner("OR", 10, JoinerApply.INFIX, "cts:or-query", Tokenize.WORD),
+            		                                       builder.joiner("AND", 20, JoinerApply.INFIX, "cts:and-query", Tokenize.WORD),
+            		                                       builder.joiner(":", 50, JoinerApply.CONSTRAINT)),
+            		                       "\"",
+            		                       Utilities.domElement("")));
+             
+        // write query options
+        optionsMgr.writeOptions("GrammarPrecedenceAndNegate", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("GrammarPrecedenceAndNegate", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("GrammarPrecedenceAndNegate");
+	    querydef.setCriteria("-bush AND -memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0024", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0113", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+		
+
+@SuppressWarnings("deprecation")
+@Test	public void testGrammarConstraint() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testGrammarConstraint");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/gramar-two-words-space/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withConstraints(builder.constraint("intitle", builder.word(builder.elementTermIndex(new QName("title")))))
+              .withGrammar(builder.grammar(builder.starters(builder.starterGrouping("(", 30, ")"),
+            		                                        builder.starterPrefix("-", 20, "cts:not-query")),	
+            		                       builder.joiners(builder.joiner("OR", 20, JoinerApply.INFIX, "cts:or-query", Tokenize.WORD),
+            		                                       builder.joiner("AND", 30, JoinerApply.INFIX, "cts:and-query", Tokenize.WORD),
+            		                                       builder.joiner(":", 50, JoinerApply.CONSTRAINT)),
+            		                       "\"",
+            		                       Utilities.domElement("")));
+             
+        // write query options
+        optionsMgr.writeOptions("GrammarConstraint", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("GrammarConstraint", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("GrammarConstraint");
+	    querydef.setCriteria("intitle:Vannevar AND served");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0024", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchOptions.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchOptions.java
new file mode 100644
index 000000000..7de5359dd
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchOptions.java
@@ -0,0 +1,190 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilderSearchOptions extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderSearchOptionsDB";
+	private static String [] fNames = {"TestQueryOptionBuilderSearchOptionsDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOptions1() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchOptions1");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-ops-1/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        List listOfSearchOptions = new ArrayList ();
+        listOfSearchOptions.add("checked");
+        listOfSearchOptions.add("filtered");
+        listOfSearchOptions.add("score-simple");
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false)
+                		.debug(true))
+              .withTransformResults(builder.rawResults())
+              .setSearchOptions(listOfSearchOptions);
+             
+        // write query options
+        optionsMgr.writeOptions("SearchOptions1", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("SearchOptions1", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchOptions1");
+	    querydef.setCriteria("bush");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+        String expectedSearchReport = "(cts:search(fn:collection(), cts:word-query(\"bush\", (\"lang=en\"), 1), (\"checked\",\"filtered\",\"score-simple\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOptions2() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchOptions2");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-ops-2/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        List listOfSearchOptions = new ArrayList ();
+        listOfSearchOptions.add("unchecked");
+        listOfSearchOptions.add("unfiltered");
+        listOfSearchOptions.add("score-logtfidf");
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false)
+                		.debug(true))
+              .withTransformResults(builder.rawResults())
+              .setSearchOptions(listOfSearchOptions);
+             
+        // write query options
+        optionsMgr.writeOptions("SearchOptions2", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("SearchOptions2", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchOptions2");
+	    querydef.setCriteria("bush");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+        String expectedSearchReport = "(cts:search(fn:collection(), cts:word-query(\"bush\", (\"lang=en\"), 1), (\"unchecked\",\"unfiltered\",\"score-logtfidf\"), 1))[1 to 10]";
+		
+		assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchableExpression.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchableExpression.java
new file mode 100644
index 000000000..04e5cb39f
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSearchableExpression.java
@@ -0,0 +1,392 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import java.io.FileNotFoundException;
+
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilderSearchableExpression extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderSearchableExpressionDB";
+	private static String [] fNames = {"TestQueryOptionBuilderSearchableExpressionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchableExpressionChildAxis() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchableExpressionChildAxis");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-expr-child-axis/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSearchableExpression(builder.searchableExpression("//root/child::p"));
+             
+        // write query options
+        optionsMgr.writeOptions("SearchableExpressionChildAxis", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("SearchableExpressionChildAxis", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	    //assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchableExpressionChildAxis");
+		querydef.setCriteria("bush");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article described a device called a Memex.", "string(//*[local-name()='result'][1]//*[local-name()='p'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush wrote an article for The Atlantic Monthly", "string(//*[local-name()='result'][2]//*[local-name()='p'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchableExpressionDescendantAxis() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchableExpressionDescendantAxis");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-expr-desc-axis/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSearchableExpression(builder.searchableExpression("/root/descendant::title"));
+             
+        // write query options
+        optionsMgr.writeOptions("SearchableExpressionDescendantAxis", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("SearchableExpressionDescendantAxis", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	    //assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchableExpressionDescendantAxis");
+		querydef.setCriteria("bush OR memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][2]//*[local-name()='title'])", resultDoc);
+		assertXpathEvaluatesTo("The memex", "string(//*[local-name()='result'][3]//*[local-name()='title'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchableExpressionOrOperator() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchableExpressionOrOperator");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-expr-or-op/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.snippetTransform(30, 4, 200))
+              .withSearchableExpression(builder.searchableExpression("//(title|id)"));
+             
+        // write query options
+        optionsMgr.writeOptions("SearchableExpressionOrOperator", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("SearchableExpressionOrOperator", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	    //assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchableExpressionOrOperator");
+		querydef.setCriteria("bush OR 0011");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Bush", "string(//*[local-name()='result'][1]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Bush", "string(//*[local-name()='result'][3]//*[local-name()='highlight'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchableExpressionDescendantOrSelf() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchableExpressionDescendantOrSelf");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-expr-desc-or-self/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.snippetTransform(30, 10, 200))
+              .withSearchableExpression(builder.searchableExpression("/descendant-or-self::root"));
+             
+        // write query options
+        optionsMgr.writeOptions("SearchableExpressionDescendantOrSelf", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("SearchableExpressionDescendantOrSelf", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	    //assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchableExpressionDescendantOrSelf");
+		querydef.setCriteria("Bush");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='match'][1])", resultDoc);
+		//assertXpathEvaluatesTo("Vannevar Bush wrote an article for The Atlantic Monthly", "string(//*[local-name()='result'][1]//*[local-name()='match'][2])", resultDoc);
+		//assertXpathEvaluatesTo("The Bush article", "string(//*[local-name()='result'][2]//*[local-name()='match'][1])", resultDoc);
+		//assertXpathEvaluatesTo("The Bush article described a device called a Memex.", "string(//*[local-name()='result'][2]//*[local-name()='match'][2])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchableExpressionFunction() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchableExpressionFunction");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/search-expr-func/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.snippetTransform(30, 10, 200))
+              .withSearchableExpression(builder.searchableExpression("//p[contains(.,\"groundbreaking\")]"));
+             
+        // write query options
+        optionsMgr.writeOptions("SearchableExpressionFunction", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("SearchableExpressionFunction", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	    //assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SearchableExpressionFunction");
+		querydef.setCriteria("atlantic");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/search-expr-func/constraint3.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+		
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSortOrder.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSortOrder.java
new file mode 100644
index 000000000..60b6aa4dd
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderSortOrder.java
@@ -0,0 +1,328 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.admin.config.QueryOptions.QuerySortOrder.Direction;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilderSortOrder extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderSortOrderDB";
+	private static String [] fNames = {"TestQueryOptionBuilderSortOrderDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSortOrderDescendingScore() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSortOrderDescendingScore");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/sort-desc-score/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSortOrders(builder.sortByScore(Direction.DESCENDING));
+               
+        // write query options
+        optionsMgr.writeOptions("SortOrderDescendingScore", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("SortOrderDescendingScore", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SortOrderDescendingScore");
+		querydef.setCriteria("bush OR memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][3]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSortOrderPrimaryDescScoreSecondaryAscDate() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSortOrderPrimaryDescScoreSecondaryAscDate");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/sort-desc-score-asc-date/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSortOrders(builder.sortByScore(Direction.DESCENDING), builder.sortOrder(builder.elementRangeIndex(new QName("http://purl.org/dc/elements/1.1/", "date"), builder.rangeType("xs:date")), Direction.ASCENDING));
+             
+        // write query options
+        optionsMgr.writeOptions("SortOrderPrimaryDescScoreSecondaryAscDate", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("SortOrderPrimaryDescScoreSecondaryAscDate", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output + "testSortOrderPrimaryDescScoreSecondaryAscDate");
+	    
+	    //String expectedOutput = "{\"options\":{\"sort-order\":[{\"direction\":\"descending\", \"score\":null},{\"direction\":\"ascending\", \"type\":\"xs:date\", \"element\":{\"name\":\"date\",\"ns\":\"http:\\/\\/purl.org\\/dc\\/elements\\/1.1\\/\"}}], \"return-metrics\":false, \"return-qtext\":false, \"transform-results\":{\"apply\":\"raw\"}}}";
+	      String expectedOutput = "{\"options\":{\"return-metrics\":false, \"return-qtext\":false, \"sort-order\":[{\"direction\":\"descending\", \"score\":null}, {\"type\":\"xs:date\", \"direction\":\"ascending\", \"element\":{\"ns\":\"http:\\/\\/purl.org\\/dc\\/elements\\/1.1\\/\", \"name\":\"date\"}}], \"transform-results\":{\"apply\":\"raw\"}}}";
+	    assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SortOrderPrimaryDescScoreSecondaryAscDate");
+		querydef.setCriteria("bush OR memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][3]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testMultipleSortOrder() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testMultipleSortOrder");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/mult-sort-order/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSortOrders(builder.sortByScore(Direction.DESCENDING), 
+            		          builder.sortOrder(builder.elementRangeIndex(new QName("", "popularity"), builder.rangeType("xs:int")), Direction.ASCENDING),
+            		          builder.sortOrder(builder.elementRangeIndex(new QName("", "title"), builder.rangeType("xs:string")), Direction.DESCENDING));
+             
+        // write query options
+        optionsMgr.writeOptions("MultipleSortOrder", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("MultipleSortOrder", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    String expectedOutput = "{\"options\":{\"return-metrics\":false, \"return-qtext\":false, \"sort-order\":[{\"direction\":\"descending\", \"score\":null}, {\"type\":\"xs:int\", \"direction\":\"ascending\", \"element\":{\"ns\":\"\", \"name\":\"popularity\"}}, {\"type\":\"xs:string\", \"direction\":\"descending\", \"element\":{\"ns\":\"\", \"name\":\"title\"}}], \"transform-results\":{\"apply\":\"raw\"}}}";
+	    assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("MultipleSortOrder");
+		querydef.setCriteria("Vannevar OR memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0024", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][3]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][4]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	} 
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSortOrderAttribute() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSortOrderAttribute");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/attr-sort-order/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.rawResults())
+              .withSortOrders(builder.sortByScore(Direction.DESCENDING), 
+            		          builder.sortOrder(builder.elementAttributeRangeIndex(new QName("http://cloudbank.com", "price"), new QName("", "amt"), builder.rangeType("xs:decimal")), Direction.ASCENDING));
+             
+        // write query options
+        optionsMgr.writeOptions("SortOrderAttribute", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("SortOrderAttribute", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    String expectedOutput = "{\"options\":{\"return-metrics\":false, \"return-qtext\":false, \"sort-order\":[{\"direction\":\"descending\", \"score\":null}, {\"type\":\"xs:decimal\", \"direction\":\"ascending\", \"attribute\":{\"ns\":\"\", \"name\":\"amt\"}, \"element\":{\"ns\":\"http:\\/\\/cloudbank.com\", \"name\":\"price\"}}], \"transform-results\":{\"apply\":\"raw\"}}}";
+	    assertTrue("Query Options in json is incorrect", output.contains(expectedOutput));
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("SortOrderAttribute");
+		querydef.setCriteria("Bush OR Memex");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][3]//*[local-name()='id'])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderTransformResults.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderTransformResults.java
new file mode 100644
index 000000000..9b06ff262
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionBuilderTransformResults.java
@@ -0,0 +1,175 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestQueryOptionBuilderTransformResults extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionBuilderTransformResultsDB";
+	private static String [] fNames = {"TestQueryOptionBuilderTransformResultsDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testTransformResuleWithSnippetFunction() throws FileNotFoundException, XpathException, TransformerException
+	{	
+		System.out.println("Running testTransformResuleWithSnippetFunction");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/trans-res-with-snip-func/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.snippetTransform(30, 4, 200, new QName("ns", "elem")));
+               
+        // write query options
+        optionsMgr.writeOptions("TransformResuleWithSnippetFunction", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions("TransformResuleWithSnippetFunction", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("TransformResuleWithSnippetFunction");
+		querydef.setCriteria("Atlantic groundbreaking");
+
+		// create handle
+		StringHandle resultsHandle = new StringHandle();
+		resultsHandle.setFormat(Format.JSON);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		System.out.println(resultDoc);
+		
+		String expectedResult = "{\"snippet-format\":\"snippet\",\"total\":1,\"start\":1,\"page-length\":10,\"results\":[{\"index\":1,\"uri\":\"/trans-res-with-snip-func/constraint3.xml\"";
+		assertTrue("Result is wrong", resultDoc.contains(expectedResult));
+		                
+		// release client
+	    client.release();	
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testTransformResuleWithEmptySnippetFunction() throws XpathException, TransformerException, SAXException, IOException
+	{	
+		System.out.println("Running testTransformResuleWithEmptySnippetFunction");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+				
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/trans-res-with-emp-snip-func/", "XML");
+		}
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options
+        handle.withConfiguration(builder.configure()
+                		.returnMetrics(false)
+                		.returnQtext(false))
+              .withTransformResults(builder.emptySnippets());
+               
+        // write query options
+        optionsMgr.writeOptions("TransformResuleWithEmptySnippetFunction", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("TransformResuleWithEmptySnippetFunction", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("TransformResuleWithEmptySnippetFunction");
+		querydef.setCriteria("Atlantic groundbreaking");
+
+		// create handle
+		StringHandle resultsHandle = new StringHandle();
+		resultsHandle.setFormat(Format.XML);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		System.out.println(resultDoc);
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/trans-res-with-emp-snip-func/constraint3.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		//assertXpathEvaluatesTo("groundbreaking", "string(//*[local-name()='result']//*[local-name()='highlight'][2])", resultDoc);
+                
+		// release client
+	    client.release();	
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsHandle.java
new file mode 100644
index 000000000..f5a9787e0
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsHandle.java
@@ -0,0 +1,306 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestQueryOptionsHandle extends BasicJavaClientREST {
+
+	private static String dbName = "TestQueryOptionsHandleDB";
+	private static String [] fNames = {"TestQueryOptionsHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRoundtrippingQueryOptionPOJO() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRoundtrippingQueryOptionPOJO");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/pojo-query-option/", "XML");
+		}
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+		
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		//System.out.println("Write " + queryOptionName + " to database");	
+		System.out.println("Write " + queryOptionName + " to database");
+				
+		// read query option with QueryOptionsHandle
+		QueryOptionsHandle readHandle = new QueryOptionsHandle();
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		String output = readHandle.toString();
+		
+		// write back query option with QueryOptionsHandle
+		String queryOptionNamePOJO = "valueConstraintWildCardPOJOOpt.xml";
+		optionsMgr.writeOptions(queryOptionNamePOJO, readHandle);
+		
+		// read POJO query option
+		optionsMgr.readOptions(queryOptionNamePOJO, readHandle);
+		String outputPOJO = readHandle.toString();
+		
+		boolean isQueryOptionsSame = output.equals(outputPOJO);
+		assertTrue("Query options is not the same", isQueryOptionsSame);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionNamePOJO);
+		querydef.setCriteria("id:00*2 OR id:0??6");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+		
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRoundtrippingQueryOptionPOJOAll() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRoundtrippingQueryOptionPOJOAll");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "appservicesConstraintCombinationOpt.xml";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/pojo-query-option-all/", "XML");
+		}
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+		
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		//System.out.println("Write " + queryOptionName + " to database");	
+		System.out.println("Write " + queryOptionName + " to database");
+				
+		// read query option with QueryOptionsHandle
+		QueryOptionsHandle readHandle = new QueryOptionsHandle();
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		String output = readHandle.toString();
+		System.out.println(output);
+		System.out.println("============================");
+		
+		// write back query option with QueryOptionsHandle
+		String queryOptionNamePOJO = "appservicesConstraintCombinationPOJOOpt.xml";
+		optionsMgr.writeOptions(queryOptionNamePOJO, readHandle);
+		
+		// read POJO query option
+		optionsMgr.readOptions(queryOptionNamePOJO, readHandle);
+		String outputPOJO = readHandle.toString();
+		System.out.println(outputPOJO);
+		
+		boolean isQueryOptionsSame = output.equals(outputPOJO);
+		assertTrue("Query options is not the same", isQueryOptionsSame);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionNamePOJO);
+		//querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex AND (pop:high OR pop:medium) AND price:low AND id:**11 AND date:2005-01-01 AND (para:Bush AND -para:memex)");
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+				
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRoundtrippingQueryOptionPOJOAllJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRoundtrippingQueryOptionPOJOAllJSON");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "appservicesConstraintCombinationOpt.json";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/pojo-query-option-all-json/", "XML");
+		}
+
+		// create handle
+		FileHandle handle = new FileHandle(new File("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.setFormat(Format.JSON);
+		
+		// write the files
+		//BufferedReader docStream = new BufferedReader(new FileReader("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		//handle.set(docStream);
+		
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+	
+		System.out.println("Write " + queryOptionName + " to database");
+		
+		// read query option with StringHandle
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		String output = readHandle.toString();
+		System.out.println(output);
+		System.out.println("============================");
+		
+		// write back query option with StringHandle
+		String queryOptionNamePOJO = "appservicesConstraintCombinationPOJOOpt.json";
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.writeOptions(queryOptionNamePOJO, readHandle);
+		
+		// read POJO query option
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions(queryOptionNamePOJO, readHandle);
+	    String outputPOJO = readHandle.toString();
+		System.out.println(outputPOJO);
+		
+		boolean isQueryOptionsSame = output.equals(outputPOJO);
+		assertTrue("Query options is not the same", isQueryOptionsSame);
+				
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionNamePOJO);
+		//querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex AND (pop:high OR pop:medium) AND price:low AND id:**11 AND date:2005-01-01 AND (para:Bush AND -para:memex)");
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc); 
+		
+				
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testJSONConverter() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testJSONConverter");
+		
+		//String queryOptionName = "jsonConverterOpt.json";
+		String queryOptionName = "queryValidationOpt.json";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create handle
+		FileHandle handle = new FileHandle(new File("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.setFormat(Format.JSON);
+				
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+	
+		System.out.println("Write " + queryOptionName + " to database");
+		
+		// read query option with QueryOptionsHandle
+		QueryOptionsHandle readHandle = new QueryOptionsHandle();
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		String output = readHandle.toString();
+		System.out.println(output);
+		System.out.println("============================");
+		
+		client.release();
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsListHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsListHandle.java
new file mode 100644
index 000000000..e1c712170
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestQueryOptionsListHandle.java
@@ -0,0 +1,50 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.QueryOptionsListHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestQueryOptionsListHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "QueryOptionsListHandleDB";
+	private static String [] fNames = {"QueryOptionsListHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testNPE() throws IOException, SAXException, ParserConfigurationException
+	{		
+		System.out.println("Running testNPE");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		QueryOptionsListHandle handle = new QueryOptionsListHandle();
+		
+		HashMap map = handle.getValuesMap();
+		    
+		// release client
+		client.release();
+	}
+		
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraint.java
new file mode 100644
index 000000000..08c6388fa
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraint.java
@@ -0,0 +1,64 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestRangeConstraint extends BasicJavaClientREST {
+	static String filenames[] = {"bbq1.xml", "bbq2.xml", "bbq3.xml", "bbq4.xml", "bbq5.xml"};
+	static String queryOptionName = "rangeConstraintOpt.xml"; 
+	private static String dbName = "RangeConstraintDB";
+	private static String [] fNames = {"RangeConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		addRangeElementIndex(dbName, "decimal", "http://example.com", "rating");
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testElementRangeConstraint() throws IOException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename:filenames)
+		{
+			writeDocumentReaderHandle(client, filename, "/range-constraint/", "XML");
+		}
+
+						
+		// write the query options to the database
+		setQueryOption(client, queryOptionName);
+							
+		// run the search
+		SearchHandle resultsHandle = runSearch(client, queryOptionName, "rating:5");
+		
+		// search result
+		String searchResult = returnSearchResult(resultsHandle);
+						
+		String expectedSearchResult = "|Matched 1 locations in /range-constraint/bbq4.xml|Matched 1 locations in /range-constraint/bbq3.xml";
+		System.out.println(searchResult);
+		
+		assertEquals("Search result difference", expectedSearchResult, searchResult);
+		
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintAbsoluteBucket.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintAbsoluteBucket.java
new file mode 100644
index 000000000..91ebb2935
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintAbsoluteBucket.java
@@ -0,0 +1,61 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestRangeConstraintAbsoluteBucket extends BasicJavaClientREST{
+	static String filenames[] = {"bbq1.xml", "bbq2.xml", "bbq3.xml", "bbq4.xml", "bbq5.xml"};
+	static String queryOptionName = "rangeAbsoluteBucketConstraintOpt.xml"; 
+	private static String dbName = "RangeConstraintAbsBucketDB";
+	private static String [] fNames = {"RangeConstraintAbsBucketDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		addRangeElementIndex(dbName, "int", "http://example.com", "scoville");
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRangeConstraintAbsoluteBucket() throws IOException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename:filenames)
+		{
+			writeDocumentReaderHandle(client, filename, "/range-constraint-abs-bucket/", "XML");
+		}
+						
+		// write the query options to the database
+		setQueryOption(client, queryOptionName);
+							
+		// run the search
+		SearchHandle resultsHandle = runSearch(client, queryOptionName, "heat:moderate");
+		
+		// search result
+		String searchResult = returnSearchResult(resultsHandle);
+						
+		String expectedSearchResult = "|Matched 1 locations in /range-constraint-abs-bucket/bbq1.xml|Matched 1 locations in /range-constraint-abs-bucket/bbq3.xml|Matched 1 locations in /range-constraint-abs-bucket/bbq5.xml";
+		assertEquals("Search result difference", expectedSearchResult, searchResult);
+						
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintRelativeBucket.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintRelativeBucket.java
new file mode 100644
index 000000000..97ef122b1
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRangeConstraintRelativeBucket.java
@@ -0,0 +1,59 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestRangeConstraintRelativeBucket extends BasicJavaClientREST {
+	static String filenames[] = {"bbq1.xml", "bbq2.xml", "bbq3.xml", "bbq4.xml", "bbq5.xml"};
+	static String queryOptionName = "rangeRelativeBucketConstraintOpt.xml"; 
+	private static String dbName = "RangeConstraintRelBucketDB";
+	private static String [] fNames = {"RangeConstraintRelBucketDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		addRangeElementAttributeIndex(dbName, "dateTime", "http://example.com", "entry", "", "date");
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRangeConstraintRelativeBucket() throws IOException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename:filenames)
+		{
+			writeDocumentReaderHandle(client, filename, "/range-constraint-rel-bucket/", "XML");
+		}
+						
+		// write the query options to the database
+		setQueryOption(client, queryOptionName);
+							
+		// run the search
+		SearchHandle resultsHandle = runSearch(client, queryOptionName, "date:older");
+		
+		// search result
+		String result = "Matched "+resultsHandle.getTotalResults();
+		String expectedResult = "Matched 5";
+		assertEquals("Document match difference", expectedResult, result);
+		
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRawAlert.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRawAlert.java
new file mode 100644
index 000000000..6b01ebb9f
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRawAlert.java
@@ -0,0 +1,800 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.TransformExtensionsManager;
+import com.marklogic.client.alerting.RuleDefinition;
+import com.marklogic.client.alerting.RuleDefinitionList;
+import com.marklogic.client.alerting.RuleManager;
+import com.marklogic.client.document.ServerTransform;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestRawAlert extends BasicJavaClientREST {
+
+	private static String dbName = "TestRawAlertDB";
+	private static String [] fNames = {"TestRawAlertDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlert() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlert");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		
+		// create a handle for the rule
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", writeHandle);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "atlantic";
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria(criteria);
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected = "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria "+criteria+" matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+		
+		System.out.println(expected);
+		
+		assertTrue("incorrect rule", expected.contains("RULE-TEST-1 - {rule-number=one} |"));
+		
+		// release client
+		client.release();		
+	}
+
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertUnmatched() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertUnmatched");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		
+		// create a handle for the rule
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", writeHandle);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "Memex"; // test case for unmatched rule
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria(criteria);
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		assertEquals("incorrect matching rule", 0, matchedRules.size());
+				
+		// release client
+		client.release();		
+	}
+	 	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertMultipleRules() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertMultipleRules");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+		
+		// create handle
+        InputStreamHandle ruleHandle1 = new InputStreamHandle();
+        InputStreamHandle ruleHandle2 = new InputStreamHandle();
+
+		// get the rule file
+		InputStream inputStream1 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		InputStream inputStream2 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule2.xml");
+				
+		ruleHandle1.set(inputStream1);
+		ruleHandle2.set(inputStream2);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", ruleHandle1);
+		ruleMgr.writeRule("RULE-TEST-2", ruleHandle2);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "atlantic";
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria(criteria);
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected = "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria "+criteria+" matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+		
+		System.out.println(expected);
+		
+		assertTrue("incorrect rules", expected.contains("RULE-TEST-1 - {rule-number=one}")&& expected.contains("RULE-TEST-2 - {rule-number=two}"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertUnmatchingRuleName() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertUnmatchingRuleName");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+		
+		// create handle
+        InputStreamHandle ruleHandle1 = new InputStreamHandle();
+
+		// get the rule file
+		InputStream inputStream1 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+				
+		ruleHandle1.set(inputStream1);
+        
+		String exception = "";
+		
+		// write the rule to the database
+		try
+		{
+			ruleMgr.writeRule("RULE-TEST-A", ruleHandle1); // test case for non-matching rule name
+		} catch(Exception e)
+		{
+			exception = e.toString();
+		}
+		
+		String expectedException = "Invalid content: If provided, rule name in payload must match rule name in URL";
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+		
+		// release client
+		client.release();		
+	}
+	
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertJSON");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.json");
+		
+		String ruleInJson = convertFileToString(file);
+		
+		// create a handle for the rule
+		StringHandle ruleHandle = new StringHandle(ruleInJson);
+		ruleHandle.setFormat(Format.JSON);
+        //FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1-JSON", ruleHandle);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "atlantic";
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(); // test case with string def
+		querydef.setCriteria(criteria);
+		
+		// create query def
+		//StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(); // tes case with structured query
+		//StructuredQueryDefinition termQuery1 = qb.term("Atlantic");
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected= "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+		
+		System.out.println(expected);
+		
+		assertTrue("rule is not correct", expected.contains("RULE-TEST-1-JSON - {{http://marklogic.com/rest-api}rule-number=one json}"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertStructuredQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertStructuredQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+				
+		// create a handle for the rule
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", writeHandle);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition termQuery1 = qb.term("Atlantic");
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(termQuery1, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size()); // bug, should return 1
+		
+		assertEquals("result count is not correct", 1, matchedRules.size());
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+		}
+		
+		// release client
+		client.release();		
+	}
+		
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertStructuredQueryTransform() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertStructuredQueryTransform");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+				
+		// create a handle for the rule
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", writeHandle);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition termQuery1 = qb.term("Atlantic");
+		
+		// Write the rule in Modules database of Server
+		TransformExtensionsManager transformManager= client.newServerConfigManager().newTransformExtensionsManager();
+		
+		File ruleTransform = new File("src/junit/com/marklogic/javaclient/rules/rule-transform.xqy");
+		transformManager.writeXQueryTransform("ruleTransform", new FileHandle(ruleTransform));
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();	
+		
+	    ServerTransform transform = new ServerTransform("ruleTransform");
+	    RuleDefinitionList matchedRules = ruleMatchMgr.match(termQuery1, 0L, QueryManager.DEFAULT_PAGE_LENGTH, new String[] {}, new RuleDefinitionList(), transform);
+        		
+		System.out.println(matchedRules.size()); // bug, should return 1
+		
+		assertEquals("result count is not correct", 1, matchedRules.size());
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+		}
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertCandidateRules() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertCandidateRules");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+						
+		// create handle
+        InputStreamHandle ruleHandle1 = new InputStreamHandle();
+        InputStreamHandle ruleHandle2 = new InputStreamHandle();
+        InputStreamHandle ruleHandle3 = new InputStreamHandle();
+
+		// get the rule file
+		InputStream inputStream1 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		InputStream inputStream2 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule2.xml");
+		InputStream inputStream3 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule3.xml");
+				
+		ruleHandle1.set(inputStream1);
+		ruleHandle2.set(inputStream2);
+		ruleHandle3.set(inputStream3);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", ruleHandle1);
+		ruleMgr.writeRule("RULE-TEST-2", ruleHandle2);
+		ruleMgr.writeRule("RULE-TEST-3", ruleHandle3);
+		
+		// get the json rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule3.json");
+		
+		String ruleInJson = convertFileToString(file);
+		
+		// create a handle for the rule
+		StringHandle ruleHandle4 = new StringHandle(ruleInJson);
+		ruleHandle4.setFormat(Format.JSON);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-3-JSON", ruleHandle4);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "memex";
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria(criteria);
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+		String[] candidateRules = {"RULE-TEST-1", "RULE-TEST-2", "RULE-TEST-3", "RULE-TEST-3-JSON"};
+		
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, 1,2, candidateRules, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected = "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria "+criteria+" matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+		
+		System.out.println(expected);
+		
+		if(expected.equals("RULE-TEST-3 - {rule-number=three} | RULE-TEST-3-JSON - {{http://marklogic.com/rest-api}rule-number=three json} | "))
+		{
+			assertTrue("rule is incorrect", expected.contains("RULE-TEST-3 - {rule-number=three} | RULE-TEST-3-JSON - {{http://marklogic.com/rest-api}rule-number=three json}"));
+		}
+		else if(expected.equals("RULE-TEST-3-JSON - {{http://marklogic.com/rest-api}rule-number=three json} | RULE-TEST-3 - {rule-number=three} | "))
+		{
+			assertTrue("rule is incorrect", expected.contains("RULE-TEST-3-JSON - {{http://marklogic.com/rest-api}rule-number=three json} | RULE-TEST-3 - {rule-number=three}"));
+		}
+		else
+		{
+			assertTrue("there is no matching rule", false);
+		}
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertCandidateRulesUnmatched() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertCandidateRulesUnmatched");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+						
+		// create handle
+        InputStreamHandle ruleHandle1 = new InputStreamHandle();
+        InputStreamHandle ruleHandle2 = new InputStreamHandle();
+        InputStreamHandle ruleHandle3 = new InputStreamHandle();
+
+		// get the rule file
+		InputStream inputStream1 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		InputStream inputStream2 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule2.xml");
+		InputStream inputStream3 = new FileInputStream("src/junit/com/marklogic/javaclient/rules/alertRule3.xml");
+				
+		ruleHandle1.set(inputStream1);
+		ruleHandle2.set(inputStream2);
+		ruleHandle3.set(inputStream3);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", ruleHandle1);
+		ruleMgr.writeRule("RULE-TEST-2", ruleHandle2);
+		ruleMgr.writeRule("RULE-TEST-3", ruleHandle3);
+		
+		// get the json rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule3.json");
+		
+		String ruleInJson = convertFileToString(file);
+		
+		// create a handle for the rule
+		StringHandle ruleHandle4 = new StringHandle(ruleInJson);
+		ruleHandle4.setFormat(Format.JSON);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-3-JSON", ruleHandle4);
+		
+		// create a manager for document search criteria
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// specify the search criteria for the documents
+		String criteria = "atlantic";
+		StringQueryDefinition querydef = queryMgr.newStringDefinition();
+		querydef.setCriteria(criteria);
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+		String[] candidateRules = {"gar", "bar", "foo"};
+		
+        // match the rules against the documents qualified by the criteria
+		
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(querydef, 1, 2, candidateRules, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		assertEquals("match rule is incorrect", 0, matchedRules.size());
+				
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertDocUris() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertDocUris");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule1.xml");
+		
+		//String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the rule
+		//StringHandle rawHandle = new StringHandle(combinedQuery);
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-1", writeHandle);
+				
+		// specify the search criteria for the documents
+		String[] docUris = {"/raw-alert/constraint1.xml", 
+				"/raw-alert/constraint2.xml", 
+				"/raw-alert/constraint3.xml", 
+				"/raw-alert/constraint4.xml", 
+				"/raw-alert/constraint5.xml"};
+		
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(docUris, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected = "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+		
+		System.out.println(expected);
+		
+		assertTrue("rule is incorrect", expected.contains("RULE-TEST-1 - {rule-number=one}"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawAlertDocPayload() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawAlertDocPayload");
+
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+						
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-alert/", "XML");
+		}
+		
+		// create a manager for configuring rules
+		RuleManager ruleMgr = client.newRuleManager();
+				
+		// get the rule
+        File file = new File("src/junit/com/marklogic/javaclient/rules/alertRule2.xml");
+				
+		// create a handle for the rule
+        FileHandle writeHandle = new FileHandle(file);
+        
+		// write the rule to the database
+		ruleMgr.writeRule("RULE-TEST-2", writeHandle);
+				
+		String filename = "constraint1.xml";
+		
+		// get the file
+        File doc = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+        String docContent = convertFileToString(doc);
+        StringHandle handle = new StringHandle(docContent);
+	    
+		// create a manager for matching rules
+		RuleManager ruleMatchMgr = client.newRuleManager();
+
+        // match the rules against the documents qualified by the criteria
+		RuleDefinitionList matchedRules = ruleMatchMgr.match(handle, new RuleDefinitionList());
+		
+		System.out.println(matchedRules.size());
+		
+		String expected = "";
+		
+        // iterate over the matched rules
+		Iterator ruleItr = matchedRules.iterator();
+		while (ruleItr.hasNext()) 
+		{
+			RuleDefinition rule = ruleItr.next();
+			System.out.println(
+					"document criteria matched rule "+
+					rule.getName()+" with metadata "+rule.getMetadata()
+					);
+			expected = expected + rule.getName() + " - " + rule.getMetadata() + " | ";
+		}
+
+		System.out.println(expected);
+		
+		assertTrue("rule is incorrect", expected.contains("RULE-TEST-2 - {rule-number=two}"));
+
+		// release client
+		client.release();		
+	}
+
+
+@AfterClass	public static  void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQuery.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQuery.java
new file mode 100644
index 000000000..6e7738a90
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQuery.java
@@ -0,0 +1,766 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestRawCombinedQuery extends BasicJavaClientREST {
+
+	private static String dbName = "TestRawCombinedQueryDB";
+	private static String [] fNames = {"TestRawCombinedQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug22353() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug22353");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOption.xml");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        	
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+        queryMgr.newStringDefinition("LinkResultDocumentsOpt.xml");
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Mime Type : "+resultsHandle.getMimetype());
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertEquals("application/xml",resultsHandle.getMimetype());
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryXML() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryXML");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOption.xml");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file); // bug 21107
+        //rawHandle.setMimetype("application/xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryXMLWithOptions() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryXMLWithOptions");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.setQueryValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryNoOption.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle, queryOptionName);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryXMLWithOverwriteOptions() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryXMLWithOverwriteOptions");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionCollectionOverwrite.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle, queryOptionName);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryJSONWithOverwriteOptions() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryJSONWithOverwriteOptions");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionJSONOverwrite.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file);
+        //rawHandle.setMimetype("application/xml");
+		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle, queryOptionName);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("document is not returned", resultDoc.contains("/raw-combined-query/constraint1.xml"));
+				
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryJSON");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionJSON.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file);
+        //rawHandle.setMimetype("application/xml");
+		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("document is not returned", resultDoc.contains("/raw-combined-query/constraint5.xml"));
+				
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryWildcard() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryWildcard");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionWildcard.xml");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file); // bug 21107
+        //rawHandle.setMimetype("application/xml");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryCollection() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryCollection");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionCollection.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryCombo() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryCombo");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionCombo.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryField() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryField");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/field-constraint/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionField.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='match'][2]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][3]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Bush", "string(//*[local-name()='result'][2]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+			   	
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryPathIndex() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryPathIndex");
+		
+		String[] filenames = {"pathindex1.xml", "pathindex2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-raw/", "XML");
+		}		
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionPathIndex.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-raw/pathindex2.xml", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-raw/pathindex1.xml", "string(//*[local-name()='result'][2]//@*[local-name()='uri'])", resultDoc);
+			   	
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryComboJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryComboJSON");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");		
+
+	    // set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.setQueryValidation(false);
+		srvMgr.writeConfiguration();
+						
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionComboJSON.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+ 		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("total document returned is incorrect", resultDoc.contains("\"total\":1"));
+		assertTrue("returned doc is incorrect", resultDoc.contains("\"uri\":\"/collection-constraint/constraint1.xml\""));
+				
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryFieldJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryFieldJSON");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/field-constraint/", "XML");
+		}
+		
+	    // set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.setQueryValidation(false);
+		srvMgr.writeConfiguration();
+				
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionFieldJSON.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+		rawHandle.setFormat(Format.JSON);		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("total document returned is incorrect", resultDoc.contains("\"total\":2"));
+		assertTrue("returned doc is incorrect", resultDoc.contains("\"uri\":\"/field-constraint/constraint5.xml\""));
+		assertTrue("returned doc is incorrect", resultDoc.contains("\"uri\":\"/field-constraint/constraint1.xml\""));
+		
+		// release client
+		client.release();		
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQueryGeo.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQueryGeo.java
new file mode 100644
index 000000000..3be461c60
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRawCombinedQueryGeo.java
@@ -0,0 +1,348 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestRawCombinedQueryGeo extends BasicJavaClientREST {
+
+	private static String dbName = "TestRawCombinedQueryGeoDB";
+	private static String [] fNames = {"TestRawCombinedQueryGeoDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeo() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryGeo");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeo.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryGeoJSON");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoJSON.json");
+        
+        String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+		rawHandle.setFormat(Format.JSON);		
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("total document returned is incorrect", resultDoc.contains("\"total\":1"));
+		assertTrue("returned doc is incorrect", resultDoc.contains("\"uri\":\"/geo-constraint/geo-constraint1.xml\""));
+		assertTrue("matched text is incorrect", resultDoc.contains("\"match-text\":[\"karl_kara 12,5 12,5 12 5\"]"));
+			
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoBoxAndWordJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryGeoBoxAndWordJSON");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWordJSON.json");
+        
+        String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+		rawHandle.setFormat(Format.JSON);		
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+
+		assertTrue("total document returned is incorrect", resultDoc.contains("\"total\":1"));
+		assertTrue("returned doc is incorrect", resultDoc.contains("\"uri\":\"/geo-constraint/geo-constraint20.xml\""));	
+			
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoCircle() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testRawCombinedQueryGeoCircle");
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoCircle.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,-5 12,-5 12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,-5 11,-5 11 -5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,-4 12,-4 12 -4", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("bill_kara 13,-5 13,-5 13 -5", "string(//*[local-name()='result'][4]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_gale 12,-6 12,-6 12 -6", "string(//*[local-name()='result'][5]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoBox() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("testRawCombinedQueryGeoBox");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoBox.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("karl_kara 12,-5 12,-5 12 -5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("jack_kara 11,-5 11,-5 11 -5", "string(//*[local-name()='result'][2]//*[local-name()='match'])", resultDoc);
+		assertXpathEvaluatesTo("karl_jill 12,-4 12,-4 12 -4", "string(//*[local-name()='result'][3]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoBoxAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryGeoBoxAndWord");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWord.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint20.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRawCombinedQueryGeoPointAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawCombinedQueryGeoPointAndWord");
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 9; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionGeoPointAndWord.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint8.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRawStructuredQuery.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRawStructuredQuery.java
new file mode 100644
index 000000000..804489fa9
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRawStructuredQuery.java
@@ -0,0 +1,551 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+import com.marklogic.client.query.RawStructuredQueryDefinition;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.io.StringHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+import org.junit.Assert;
+public class TestRawStructuredQuery extends BasicJavaClientREST {
+
+	
+	private static String dbName = "TestRawStructuredQueryDB";
+	private static String [] fNames = {"TestRawStructuredQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	  System.out.println("after setup");
+	}
+	
+
+
+@Test	public void testRawStructuredQueryXML() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryXML");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOption.xml");
+		
+		// create a handle for the search criteria
+	    FileHandle rawHandle = new FileHandle(file);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryJSON");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionJSON.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file);
+        //rawHandle.setMimetype("application/xml");
+		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+		RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("document is not returned", resultDoc.contains("/raw-combined-query/constraint5.xml"));
+				
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryXMLWithOptions() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryXMLWithOptions");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+				
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryNoOption.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle, queryOptionName);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryJSONWithOverwriteOptions() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryJSONWithOverwriteOptions");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWithoutIndexSettingsAndNSOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/raw-combined-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionJSONOverwrite.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+        //FileHandle rawHandle = new FileHandle(file);
+        //rawHandle.setMimetype("application/xml");
+		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle, queryOptionName);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("document is not returned", resultDoc.contains("/raw-combined-query/constraint1.xml"));
+				
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryCollection() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryCollection");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionCollection.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+		RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+	
+
+
+@Test	public void testRawStructuredQueryCombo() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryCombo");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+	    
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionCombo.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+		RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryField() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryField");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/field-constraint/", "XML");
+		}
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionField.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+		RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='match'][2]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Memex", "string(//*[local-name()='result'][1]//*[local-name()='match'][3]//*[local-name()='highlight'])", resultDoc);
+		assertXpathEvaluatesTo("Bush", "string(//*[local-name()='result'][2]//*[local-name()='match'][1]//*[local-name()='highlight'])", resultDoc);
+			   	
+		// release client
+		client.release();		
+	}
+	
+
+
+@Test	public void testRawStructuredQueryPathIndex() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryPathIndex");
+		
+		String[] filenames = {"pathindex1.xml", "pathindex2.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/path-index-raw/", "XML");
+		}		
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionPathIndex.xml");
+		
+		// create a handle for the search criteria
+        FileHandle rawHandle = new FileHandle(file); // bug 21107
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+		RawStructuredQueryDefinition querydef = queryMgr.newRawStructuredQueryDefinition(rawHandle);
+		
+		// create result handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-raw/pathindex2.xml", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("/path-index-raw/pathindex1.xml", "string(//*[local-name()='result'][2]//@*[local-name()='uri'])", resultDoc);
+			   	
+		// release client
+		client.release();		
+	}
+	
+	/*public void testRawStructuredQueryComboJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testRawStructuredQueryComboJSON");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");		
+
+	    // set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+						
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOptionComboJSON.json");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+ 		rawHandle.setFormat(Format.JSON);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+		
+		// create result handle
+		StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		//assertTrue("document is not returned", resultDoc.contains("/raw-combined-query/constraint5.xml"));
+				
+		// release client
+		client.release();		
+	}*/
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestReaderHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestReaderHandle.java
new file mode 100644
index 000000000..a469cebc4
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestReaderHandle.java
@@ -0,0 +1,325 @@
+package com.marklogic.javaclient;
+
+import java.io.*;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.XMLUnit;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.ReaderHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestReaderHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "WriteReaderHandleDB";
+	private static String [] fNames = {"WriteReaderHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testXmlCRUD() throws FileNotFoundException, IOException, SAXException, ParserConfigurationException
+	{
+		System.out.println("Running testXmlCRUD");
+		
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-readerhandle/";
+				
+		XMLUnit.setIgnoreWhitespace(true);
+		XMLUnit.setNormalizeWhitespace(true);
+		
+		// connect the client
+	    DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+			
+	    // write the doc
+	    writeDocumentReaderHandle(client, filename, uri, "XML");
+	    
+	    // read the document
+	    ReaderHandle readHandle = readDocumentReaderHandle(client, uri + filename, "XML");
+	    
+	    // access the document content
+	    Reader fileRead = readHandle.get();
+	    	    
+	    String readContent = convertReaderToString(fileRead);
+	    
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+
+		assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+	    
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentReaderHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    ReaderHandle updateHandle = readDocumentReaderHandle(client, uri + filename, "XML");
+	    
+	    // access the document content
+	    Reader fileReadUpdate = updateHandle.get();
+	        
+	    String readContentUpdate = convertReaderToString(fileReadUpdate);
+	    
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+		// convert actual string to xml doc
+		Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+
+		assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+		
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, "/write-xml-readerhandle/" + filename, "XML"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+
+	        
+	    // release the client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testTextCRUD() throws FileNotFoundException, IOException
+	{
+		System.out.println("Running testTextCRUD");
+		
+		String filename = "text-original.txt";
+		String uri = "/write-text-readerhandle/";
+		
+		// connect the client
+	    DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+			
+	    // write the doc
+	    writeDocumentReaderHandle(client, filename, uri, "Text");
+	    
+	    // read the document
+	    ReaderHandle readHandle = readDocumentReaderHandle(client, uri + filename, "Text");
+	    
+	    // access the document content
+	    Reader fileRead = readHandle.get();
+	    
+	    String expectedContent = "hello world, welcome to java API";
+	    
+	    String readContent = convertReaderToString(fileRead);
+	    
+	    assertEquals("Write Text document difference", expectedContent, readContent);
+	    
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "text-updated.txt";
+	    updateDocumentReaderHandle(client, updateFilename, uri + filename, "Text");
+	    
+	    // read the document
+	    ReaderHandle updateHandle = readDocumentReaderHandle(client, uri + filename, "Text");
+	    
+	    // access the document content
+	    Reader fileReadUpdate = updateHandle.get();
+	    
+	    String readContentUpdate = convertReaderToString(fileReadUpdate);
+	    
+	    String expectedContentUpdate = "hello world, welcome to java API after new updates";
+	    
+	    assertEquals("Update Text document difference", expectedContentUpdate, readContentUpdate);
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "Text");
+		
+		// read the deleted document
+	    // assertFalse("Document is not deleted", isDocumentExist(client, "/write-text-readerhandle/" + filename, "Text"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "Text");
+	    } catch (Exception e) { exception = e.toString(); }
+    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+	    	    
+	    // release the client
+	    client.release();
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testJsonCRUD() throws FileNotFoundException, IOException
+	{
+		System.out.println("Running testJsonCRUD");
+		
+		String filename = "json-original.json";
+		String uri = "/write-json-readerhandle/";
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// connect the client
+	    DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+			
+	    // write the doc
+	    writeDocumentReaderHandle(client, filename, uri, "JSON");
+	    
+	    // read the document
+	    ReaderHandle readHandle = readDocumentReaderHandle(client, uri + filename, "JSON");
+	    
+	    // access the document content
+	    Reader fileRead = readHandle.get();
+		JsonNode readContent = mapper.readTree(fileRead);
+		
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+		
+		assertTrue("Write JSON document difference", readContent.equals(expectedContent));	    
+	    
+	    //assertEquals("Write JSON document difference", expectedContent, readContent);
+	    
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "json-updated.json";
+	    updateDocumentReaderHandle(client, updateFilename, uri + filename, "JSON");
+	    
+	    // read the document
+	    ReaderHandle updateHandle = readDocumentReaderHandle(client, uri + filename, "JSON");
+	    
+	    // access the document content
+	    Reader fileReadUpdate = updateHandle.get();
+		JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+		
+		// get expected contents
+		JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+		
+		assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));	    
+	    
+		// delete the document
+	    deleteDocument(client, uri + filename, "JSON");
+		
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, "/write-json-readerhandle/" + filename, "JSON"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "JSON");
+	    } catch (Exception e) { exception = e.toString(); }
+
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+
+	    // release the client
+	    client.release();
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBinaryCRUD() throws IOException
+	{	
+		String filename = "Pandakarlino.jpg";
+		String uri = "/write-bin-filehandle/";
+		
+		System.out.println("Running testBinaryCRUD");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		writeDocumentReaderHandle(client, filename, uri, "Binary");	
+		
+		// read docs
+		ReaderHandle contentHandle = readDocumentReaderHandle(client, uri+filename, "Binary");
+		
+		// get the contents
+		Reader fileRead = contentHandle.get();
+		
+		// get the binary size
+		long size = convertReaderToString(fileRead).length();
+		//long expectedSize = 17031;
+		
+		boolean expectedSize;
+		if(size >= 16800 && size <= 17200)
+		{
+			expectedSize = true;
+			assertTrue("Binary size difference", expectedSize);
+		}
+		
+		// update the doc
+	    // acquire the content for update
+	    String updateFilename = "mlfavicon.png";
+		//String updateFilename = "JenoptikLogo.jpg";
+	    updateDocumentReaderHandle(client,updateFilename, uri+filename, "Binary");
+	    
+	    
+	    // read the document
+	    ReaderHandle updateHandle = readDocumentReaderHandle(client, uri+filename, "Binary");
+		
+	    
+	    // get the contents
+	    Reader fileReadUpdate = updateHandle.get();
+
+	    // get the binary size
+	    long sizeUpdate = convertReaderToString(fileReadUpdate).length();
+	    //long expectedSizeUpdate = 56508;
+	    
+		boolean expectedSizeUpdate;
+		if(sizeUpdate >= 55000 && sizeUpdate <= 57000)
+		{
+			expectedSizeUpdate = true;
+			assertTrue("Binary size difference", expectedSizeUpdate);
+		}
+	    
+		//assertEquals("Binary size difference", expectedSizeUpdate, sizeUpdate);
+		
+		// delete the document
+	    deleteDocument(client, uri + filename, "Binary");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Binary"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "Binary");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-bin-filehandle/Pandakarlino.jpg";
+	    assertEquals("Document is not deleted", expectedException, exception);
+
+			    
+	    // release client
+		client.release();
+	}
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+		}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRequestLogger.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRequestLogger.java
new file mode 100644
index 000000000..578a75095
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRequestLogger.java
@@ -0,0 +1,83 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.util.RequestLogger;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.FileHandle;
+import org.junit.*;
+public class TestRequestLogger extends BasicJavaClientREST {
+
+	private static String dbName = "TestRequestLoggerDB";
+	private static String [] fNames = {"TestRequestLoggerDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRequestLogger()
+	{	
+		System.out.println("testRequestLogger");
+		
+		String filename = "bbq1.xml";
+		String uri = "/request-logger/";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// create transaction
+		Transaction transaction = client.openTransaction();
+		
+		// create a manager for XML documents
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = uri + filename;
+
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    
+	    // create logger
+		RequestLogger logger = client.newLogger(System.out);
+		logger.setContentMax(RequestLogger.ALL_CONTENT);
+		
+		// start logging
+		docMgr.startLogging(logger);
+
+	    // write the document content
+	    docMgr.write(docId, handle, transaction);
+		
+	    // commit transaction
+		transaction.commit();		
+		
+		// stop logging
+		docMgr.stopLogging();
+		
+		String expectedContentMax = "9223372036854775807";
+		assertEquals("Content log is not equal", expectedContentMax, Long.toString(logger.getContentMax()));
+		
+		// release client
+	    client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestResponseTransform.java b/test-complete/src/test/java/com/marklogic/javaclient/TestResponseTransform.java
new file mode 100644
index 000000000..d10f60078
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestResponseTransform.java
@@ -0,0 +1,200 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.RawCombinedQueryDefinition;
+
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ExtensionMetadata;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.admin.TransformExtensionsManager;
+import com.marklogic.client.document.ServerTransform;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestResponseTransform extends BasicJavaClientREST {
+
+	private static String dbName = "TestResponseTransformDB";
+	private static String [] fNames = {"TestResponseTransformDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testResponseTransform() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testResponseTransform");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/response-transform/", "XML");
+		}
+		
+		// set the transform		
+		// create a manager for transform extensions
+		TransformExtensionsManager transMgr = client.newServerConfigManager().newTransformExtensionsManager();
+
+		// specify metadata about the transform extension
+		ExtensionMetadata metadata = new ExtensionMetadata();
+		metadata.setTitle("Search-Response-TO-HTML XSLT Transform");
+		metadata.setDescription("This plugin transforms a Search Response document to HTML");
+		metadata.setProvider("MarkLogic");
+		metadata.setVersion("0.1");
+		
+		// get the transform file
+		File transformFile = new File("src/junit/com/marklogic/javaclient/transforms/search2html.xsl");
+		
+		FileHandle transformHandle = new FileHandle(transformFile);
+		
+		// write the transform
+		transMgr.writeXSLTransform("search2html", transformHandle, metadata);
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOption.xml");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+        querydef.setResponseTransform(new ServerTransform("search2html"));
+		
+		// create result handle
+        StringHandle resultsHandle = new StringHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultDoc = resultsHandle.get();
+		
+		System.out.println(resultDoc);
+		
+		assertTrue("transform on title is not found", resultDoc.contains("Custom Search Results"));
+		assertTrue("transform on header is not found", resultDoc.contains("MyURI"));
+		assertTrue("transform on doc return is not found", resultDoc.contains("/response-transform/constraint5.xml"));
+	    		
+		transMgr.deleteTransform("search2html");
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testResponseTransformInvalid() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testResponseTransformInvalid");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/response-transform/", "XML");
+		}
+		
+		// set the transform		
+		// create a manager for transform extensions
+		TransformExtensionsManager transMgr = client.newServerConfigManager().newTransformExtensionsManager();
+
+		// specify metadata about the transform extension
+		ExtensionMetadata metadata = new ExtensionMetadata();
+		metadata.setTitle("Search-Response-TO-HTML XSLT Transform");
+		metadata.setDescription("This plugin transforms a Search Response document to HTML");
+		metadata.setProvider("MarkLogic");
+		metadata.setVersion("0.1");
+		
+		// get the transform file
+		File transformFile = new File("src/junit/com/marklogic/javaclient/transforms/search2html.xsl");
+		
+		FileHandle transformHandle = new FileHandle(transformFile);
+		
+		// write the transform
+		transMgr.writeXSLTransform("search2html", transformHandle, metadata);
+		
+		// get the combined query
+        File file = new File("src/junit/com/marklogic/javaclient/combined/combinedQueryOption.xml");
+		
+		String combinedQuery = convertFileToString(file);
+		
+		// create a handle for the search criteria
+		StringHandle rawHandle = new StringHandle(combinedQuery);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create a search definition based on the handle
+        RawCombinedQueryDefinition querydef = queryMgr.newRawCombinedQueryDefinition(rawHandle);
+        querydef.setResponseTransform(new ServerTransform("foo"));
+		
+		// create result handle
+        StringHandle resultsHandle = new StringHandle();
+        
+        String exception = "";
+        
+        try
+        {
+        	queryMgr.search(querydef, resultsHandle);
+        } catch(Exception e)
+        {
+        	exception = e.toString();
+        	System.out.println(exception);
+        }
+        
+        String expectedException = "Local message: search failed: Bad Request. Server Message: XDMP-MODNOTFOUND: (err:XQST0059) Module /marklogic.rest.transform/foo/assets/transform.xqy not found";
+        assertTrue("exception is not thrown", exception.contains(expectedException));
+	    //bug 22356
+        assertTrue("Value should be null", resultsHandle.get()==null);
+        
+		transMgr.deleteTransform("search2html");
+		
+		// release client
+		client.release();		
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestRollbackTransaction.java b/test-complete/src/test/java/com/marklogic/javaclient/TestRollbackTransaction.java
new file mode 100644
index 000000000..330fc5eed
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestRollbackTransaction.java
@@ -0,0 +1,327 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import org.junit.*;
+public class TestRollbackTransaction extends BasicJavaClientREST {
+
+	private static String dbName = "TestRollbackTransactionDB";
+	private static String [] fNames = {"TestRollbackTransactionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+
+@Test	public void testRollbackDeleteDocument() throws ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testRollbackDeleteDocument");
+		
+		String filename = "bbq1.xml";
+		String uri = "/tx-rollback/";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// create transaction 1
+		Transaction transaction1 = client.openTransaction();
+		
+		// create a manager for document
+		DocumentManager docMgr = client.newDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = uri + filename;
+
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    handle.setFormat(Format.XML);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle, transaction1);
+		
+	    // commit transaction
+		transaction1.commit();		
+		
+		// create transaction 2
+		Transaction transaction2 = client.openTransaction();
+				
+		// delete document
+		docMgr.delete(docId, transaction2);
+		
+		// commit transaction
+		//transaction2.commit();
+		
+		// rollback transaction
+		transaction2.rollback();
+		
+		// read document
+		FileHandle readHandle = new FileHandle();
+		docMgr.read(docId, readHandle);
+		File fileRead = readHandle.get();
+		String readContent = convertFileToString(fileRead);
+		
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Rollback on document delete failed", expectedDoc, readDoc);
+		
+		// release client
+	    client.release();
+	}
+	
+
+
+@Test	public void testRollbackUpdateDocument() throws ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testRollbackUpdateDocument");
+		
+		String filename = "json-original.json";
+		String updateFilename = "json-updated.json";
+		String uri = "/tx-rollback/";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// create transaction 1
+		Transaction transaction1 = client.openTransaction();
+		
+		// create a manager for document
+		DocumentManager docMgr = client.newDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = uri + filename;
+
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    handle.setFormat(Format.JSON);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle, transaction1);
+		
+	    // commit transaction
+		transaction1.commit();		
+		
+		// create transaction 2
+		Transaction transaction2 = client.openTransaction();
+				
+		// update document
+		File updateFile = new File("src/test/java/com/marklogic/javaclient/data/" + updateFilename);
+		FileHandle updateHandle = new FileHandle(updateFile);
+		updateHandle.set(updateFile);
+		updateHandle.setFormat(Format.JSON);
+		docMgr.write(docId, updateHandle, transaction2);
+		
+		// commit transaction
+		//transaction2.commit();
+		
+		// rollback transaction
+		transaction2.rollback();
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// read document
+		FileHandle readHandle = new FileHandle();
+		docMgr.read(docId, readHandle);
+		File fileRead = readHandle.get();
+		JsonNode readContent = mapper.readTree(fileRead);
+		
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+				
+		assertTrue("Rollback on document update failed", readContent.equals(expectedContent));		
+		
+		// release client
+	    client.release();
+	}
+	
+
+
+@Test	public void testRollbackMetadata() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{
+		System.out.println("Running testRollbackMetadata");
+		
+		String filename = "Simple_ScanTe.png";
+		String uri = "/tx-rollback/";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// create transaction 1
+		Transaction transaction1 = client.openTransaction();
+
+		// create doc manager
+		DocumentManager docMgr = client.newDocumentManager();
+		
+	    // create an identifier for the document
+	    String docId = uri + filename;
+
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    handle.setFormat(Format.BINARY);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle, transaction1);
+	    
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+			    	    
+	    // write original metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandle, transaction1);
+		
+	    // commit transaction
+		transaction1.commit();		
+
+		// create transaction 2
+		Transaction transaction2 = client.openTransaction();
+	    
+		// get the update metadata
+		Document docMetadataUpdate = getXMLMetadata("metadata-updated.xml");
+
+		// create handle for metadata update
+		DOMHandle writeMetadataHandleUpdate = new DOMHandle();
+		writeMetadataHandleUpdate.set(docMetadataUpdate);
+		
+		// write updated metadata
+	    docMgr.writeMetadata(docId, writeMetadataHandleUpdate, transaction2);
+	    
+	    // commit transaction2
+	    //transaction2.commit();
+	    
+	    // rollback transaction2
+	    transaction2.rollback();
+	    
+	    // create handle to read updated metadata
+	    DOMHandle readMetadataHandleUpdate = new DOMHandle();
+
+	    // read updated metadata
+	    docMgr.readMetadata(docId, readMetadataHandleUpdate);
+	    Document docReadMetadataUpdate = readMetadataHandleUpdate.get();
+	    
+	    assertXpathEvaluatesTo("coll1", "string(//*[local-name()='collection'][1])", docReadMetadataUpdate);
+	    assertXpathEvaluatesTo("coll2", "string(//*[local-name()='collection'][2])", docReadMetadataUpdate);
+	    assertXpathEvaluatesTo("MarkLogic", "string(//*[local-name()='Author'])", docReadMetadataUpdate);
+	    
+	    // release the client
+	    client.release();
+	}	
+	
+
+
+@Test	public void testNegative() throws ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("testNegative");
+		
+		String filename = "bbq1.xml";
+		String uri = "/tx-rollback/";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+		
+		// create transaction 1
+		Transaction transaction1 = client.openTransaction();
+		
+		// create a manager for document
+		DocumentManager docMgr = client.newDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = uri + filename;
+
+	    // create a handle on the content
+	    FileHandle handle = new FileHandle(file);
+	    handle.set(file);
+	    handle.setFormat(Format.XML);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle, transaction1);
+		
+	    // commit transaction
+		transaction1.commit();		
+		
+		// create transaction 2
+		Transaction transaction2 = client.openTransaction();
+				
+		// delete document
+		docMgr.delete(docId, transaction2);
+		
+		// commit transaction
+		transaction2.commit();
+		
+		String expectedException = "com.marklogic.client.FailedRequestException: Local message: transaction rollback failed: Bad Request. Server Message: XDMP-NOTXN";
+		String exception = "";
+		
+		// rollback transaction
+		try
+		{
+			transaction2.rollback();
+		} catch(Exception e) { exception = e.toString(); };
+		
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+		
+		/*
+		// read document
+		FileHandle readHandle = new FileHandle();
+		docMgr.read(docId, readHandle);
+		File fileRead = readHandle.get();
+		String readContent = convertFileToString(fileRead);
+		
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Rollback on document delete failed", expectedDoc, readDoc);
+		*/
+		
+		// release client
+	    client.release();
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSSLConnection.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSSLConnection.java
new file mode 100644
index 000000000..416e358b0
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSSLConnection.java
@@ -0,0 +1,391 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.xml.namespace.QName;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.DatabaseClientFactory.SSLHostnameVerifier;
+import com.marklogic.client.admin.config.QueryOptionsBuilder;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.QueryOptionsHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestSSLConnection extends BasicJavaClientREST {
+
+	private static String dbName = "TestSSLConnectionDB";
+	private static String [] fNames = {"TestSSLConnectionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-SSL-Server";
+
+	protected void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8033);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+	/*
+	 * 
+
+	@SuppressWarnings("deprecation")
+	@Test	 public void testSSLConnection() throws NoSuchAlgorithmException, KeyManagementException, FileNotFoundException, XpathException
+	{	
+		System.out.println("Running testSSLConnection");
+		
+		// create a trust manager
+		// (note: a real application should verify certificates)
+		TrustManager naiveTrustMgr = new X509TrustManager() {
+			@Override
+			public void checkClientTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public void checkServerTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		};
+
+		// create an SSL context
+		SSLContext sslContext = SSLContext.getInstance("SSLv3");
+		sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		
+		// create the client
+		// (note: a real application should use a COMMON, STRICT, or implemented hostname verifier)
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8012, "rest-admin", "x", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/ssl-connection/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/ssl-connection/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/ssl-connection/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/ssl-connection/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/ssl-connection/", metadataHandle5, "XML");
+		
+		// create query options manager
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+		
+		// create query options builder
+		QueryOptionsBuilder builder = new QueryOptionsBuilder();
+		
+		// create query options handle
+        QueryOptionsHandle handle = new QueryOptionsHandle();
+        
+        // build query options		
+	
+        handle.build(
+        		builder.returnMetrics(false), 
+                builder.returnQtext(false),
+                builder.debug(true), 
+                builder.transformResults("raw"),
+                builder.constraint("id", 
+                        builder.value(builder.element("id"))),
+                builder.constraint("date",
+                		builder.range(false, new QName("xs:date"), builder.element("http://purl.org/dc/elements/1.1/", "date"))),                                
+                builder.constraint("coll", 
+                        builder.collection(true, "http://test.com/")),        
+                builder.constraint("para",
+                		builder.word(builder.field("para"),
+                					 builder.termOption("case-insensitive"))),
+                builder.constraint("intitle",
+                		builder.word(builder.element("title"))),
+                builder.constraint("price",
+                        builder.range(false, new QName("xs:decimal"), 
+                                      builder.element("http://cloudbank.com", "price"),
+                                      builder.attribute("amt"),
+                                	  builder.bucket("high", "High", "120", null),
+                                	  builder.bucket("medium", "Medium", "3", "14"),
+                                	  builder.bucket("low", "Low", "0", "2"))),
+                builder.constraint("pop",
+                        builder.range(true, new QName("xs:int"), 
+                                      builder.element("popularity"), 
+                                      builder.bucket("high", "High", "5", null),
+                                      builder.bucket("medium", "Medium", "3", "5"),
+                                      builder.bucket("low", "Low", "1", "3"))) 
+        );
+
+        
+        // write query options
+        optionsMgr.writeOptions("AllConstraintsWithStructuredSearch", handle);
+        
+        // read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.XML);
+		optionsMgr.readOptions("AllConstraintsWithStructuredSearch", readHandle);
+	    String output = readHandle.get();
+	    System.out.println(output);
+	    
+	    // create query manager
+		QueryManager queryMgr = client.newQueryManager();
+				
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder("AllConstraintsWithStructuredSearch");
+		StructuredQueryDefinition query1 = qb.and(qb.collectionConstraint("coll", "set1"), qb.collectionConstraint("coll", "set5"));
+		StructuredQueryDefinition query2 = qb.not(qb.wordConstraint("intitle", "memex"));
+		StructuredQueryDefinition query3 = qb.valueConstraint("id", "**11");
+		StructuredQueryDefinition query4 = qb.rangeConstraint("date", StructuredQueryBuilder.Operator.EQ, "2005-01-01");
+		StructuredQueryDefinition query5 = qb.and(qb.wordConstraint("para", "Bush"), qb.not(qb.wordConstraint("para", "memex")));
+		StructuredQueryDefinition query6 = qb.rangeConstraint("price", StructuredQueryBuilder.Operator.EQ, "low");
+		StructuredQueryDefinition query7 = qb.or(qb.rangeConstraint("pop", StructuredQueryBuilder.Operator.EQ, "high"), qb.rangeConstraint("pop", StructuredQueryBuilder.Operator.EQ, "medium"));
+		StructuredQueryDefinition queryFinal = qb.and(query1, query2, query3, query4, query5, query6, query7);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(queryFinal, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("Vannevar Bush", "string(//*[local-name()='result'][1]//*[local-name()='title'])", resultDoc);
+                        
+		// release client
+	    client.release();	
+	}
+	*/
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testSSLConnectionInvalidPort() throws IOException, NoSuchAlgorithmException, KeyManagementException
+	{
+		System.out.println("Running testSSLConnectionInvalidPort");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// create a trust manager
+		// (note: a real application should verify certificates)
+		TrustManager naiveTrustMgr = new X509TrustManager() {
+			@Override
+			public void checkClientTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public void checkServerTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		};
+
+		// create an SSL context
+		SSLContext sslContext = SSLContext.getInstance("SSLv3");
+		sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+				
+		// create the client
+		// (note: a real application should use a COMMON, STRICT, or implemented hostname verifier)
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8033, "rest-admin", "x", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+		
+		String expectedException = "com.sun.jersey.api.client.ClientHandlerException: org.apache.http.conn.HttpHostConnectException: Connection to https://localhost:8033 refused";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		assertEquals("Exception is not thrown", expectedException, exception);
+		
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testSSLConnectionNonSSLServer() throws IOException, NoSuchAlgorithmException, KeyManagementException
+	{
+		System.out.println("Running testSSLConnectionNonSSLServer");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// create a trust manager
+		// (note: a real application should verify certificates)
+		TrustManager naiveTrustMgr = new X509TrustManager() {
+			@Override
+			public void checkClientTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public void checkServerTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		};
+
+		// create an SSL context
+		SSLContext sslContext = SSLContext.getInstance("SSLv3");
+		sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+				
+		// create the client
+		// (note: a real application should use a COMMON, STRICT, or implemented hostname verifier)
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+		
+		String expectedException = "com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		assertEquals("Exception is not thrown", expectedException, exception);
+		
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testSSLConnectionInvalidPassword() throws IOException, NoSuchAlgorithmException, KeyManagementException
+	{
+		System.out.println("Running testSSLConnectionInvalidPassword");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// create a trust manager
+		// (note: a real application should verify certificates)
+		TrustManager naiveTrustMgr = new X509TrustManager() {
+			@Override
+			public void checkClientTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public void checkServerTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		};
+
+		// create an SSL context
+		SSLContext sslContext = SSLContext.getInstance("SSLv3");
+		sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+				
+		// create the client
+		// (note: a real application should use a COMMON, STRICT, or implemented hostname verifier)
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8012, "rest-admin", "foo", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+		
+		String expectedException = "FailedRequestException: Local message: write failed: Unauthorized";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// release client
+		client.release();
+	}
+
+
+	@SuppressWarnings("deprecation")
+	@Test	public void testSSLConnectionInvalidUser() throws IOException, NoSuchAlgorithmException, KeyManagementException
+	{
+		System.out.println("Running testSSLConnectionInvalidUser");
+		
+		String filename = "facebook-10443244874876159931";
+		
+		// create a trust manager
+		// (note: a real application should verify certificates)
+		TrustManager naiveTrustMgr = new X509TrustManager() {
+			@Override
+			public void checkClientTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public void checkServerTrusted(X509Certificate[] chain, String authType) {
+			}
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		};
+
+		// create an SSL context
+		SSLContext sslContext = SSLContext.getInstance("SSLv3");
+		sslContext.init(null, new TrustManager[] { naiveTrustMgr }, null);
+				
+		// create the client
+		// (note: a real application should use a COMMON, STRICT, or implemented hostname verifier)
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8012, "MyFooUser", "x", Authentication.DIGEST, sslContext, SSLHostnameVerifier.ANY);
+
+		
+		String expectedException = "FailedRequestException: Local message: write failed: Unauthorized";
+		String exception = "";
+		
+		// write doc
+		try
+		{
+			writeDocumentUsingStringHandle(client, filename, "/write-text-doc/", "Text");
+		}
+		catch (Exception e) { exception = e.toString(); }
+		
+		boolean isExceptionThrown = exception.contains(expectedException);
+		
+		assertTrue("Exception is not thrown", isExceptionThrown);
+		
+		// release client
+		client.release();
+	}
+	
+	public void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		;
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultibyte.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultibyte.java
new file mode 100644
index 000000000..f2545c658
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultibyte.java
@@ -0,0 +1,157 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestSearchMultibyte extends BasicJavaClientREST {
+
+	private static String dbName = "TestSearchMultibyteDB";
+	private static String [] fNames = {"TestSearchMultibyteDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchString() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchString");
+		
+		String[] filenames = {"multibyte1.xml", "multibyte2.xml", "multibyte3.xml"};
+		String queryOptionName = "multibyteSearchOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/multibyte-search/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("mult-title:万里长城");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/multibyte-search/multibyte1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchStringWithBucket() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchStringWithBucket");
+		
+		String[] filenames = {"multibyte1.xml", "multibyte2.xml", "multibyte3.xml"};
+		String queryOptionName = "multibyteSearchOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/multibyte-search/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("mult-pop:medium");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/multibyte-search/multibyte2.xml", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("/multibyte-search/multibyte1.xml", "string(//*[local-name()='result'][2]//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchStringWithBucketAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchStringWithBucketAndWord");
+		
+		String[] filenames = {"multibyte1.xml", "multibyte2.xml", "multibyte3.xml"};
+		String queryOptionName = "multibyteSearchOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/multibyte-search/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("mult-pop:medium AND mult-title:上海");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/multibyte-search/multibyte2.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,restServerName);
+	}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultipleForests.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultipleForests.java
new file mode 100644
index 000000000..6589b2689
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchMultipleForests.java
@@ -0,0 +1,80 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.document.DocumentManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestSearchMultipleForests extends BasicJavaClientREST {
+	
+	private static String dbName = "TestSearchMultipleForestsDB";
+	private static String [] fNames = {"TestSearchMultipleForestsDB-1", "TestSearchMultipleForestsDB-2"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  createForest(fNames[1],dbName);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchMultipleForest() throws IOException, SAXException, ParserConfigurationException, TransformerException
+	{	
+		System.out.println("Running testSearchMultipleForest");
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		DocumentManager docMgr = client.newDocumentManager();
+		docMgr.setForestName("TestSearchMultipleForestsDB-1");
+		StringHandle writeHandle1 = new StringHandle();
+		for(int a = 1; a <= 10; a++ )
+		{
+			writeHandle1.set("hello");
+			docMgr.write("/forest-A/file" + a + ".xml", writeHandle1);
+		}
+		
+		docMgr.setForestName("TestSearchMultipleForestsDB-2");
+		StringHandle writeHandle2 = new StringHandle();
+		for(int b = 1; b <= 10; b++ )
+		{
+			writeHandle1.set("hello");
+			docMgr.write("/forest-B/file" + b + ".xml", writeHandle1);
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("");
+		querydef.setCriteria("");
+				
+		SearchHandle sHandle = new SearchHandle();
+		queryMgr.search(querydef, sHandle);
+		System.out.println(sHandle.getTotalResults());
+		assertTrue("Document count is incorrect", sHandle.getTotalResults() == 20);
+		
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnJSON.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnJSON.java
new file mode 100644
index 000000000..42dd96019
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnJSON.java
@@ -0,0 +1,189 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.marklogic.client.query.QueryManager;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.io.Format;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.StringHandle;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestSearchOnJSON extends BasicJavaClientREST {
+
+	private static String dbName = "TestSearchOnJSONDB";
+	private static String [] fNames = {"TestSearchOnJSONDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testRoundtrippingQueryOption() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testRoundtrippingQueryOption");
+		
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+		
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+		
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		System.out.println("Write " + queryOptionName + " to database");	
+		
+		// read query option
+		StringHandle readHandle = new StringHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		
+		String output = readHandle.get();
+		
+		System.out.println(output);
+		
+		String expectedOutput = "{\"options\":{\"return-metrics\":false, \"return-qtext\":false, \"debug\":true, \"transform-results\":{\"apply\":\"raw\"}, \"constraint\":[{\"name\":\"id\", \"value\":{\"element\":{\"ns\":\"\", \"name\":\"id\"}}}]}}";
+		
+		assertEquals("query option in JSON is difference", expectedOutput, output);
+		
+		// create handle to write back option in json
+		String queryOptionNameJson = queryOptionName.replaceAll(".xml", ".json");
+		StringHandle writeHandle = new StringHandle();
+		writeHandle.set(output);
+		writeHandle.setFormat(Format.JSON);
+		optionsMgr.writeOptions(queryOptionNameJson, writeHandle);
+		System.out.println("Write " + queryOptionNameJson + " to database");
+		
+		// release client
+	    client.release();	
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testWithAllConstraintSearchResultinJSON() throws IOException, ParserConfigurationException, SAXException, XpathException
+	{	
+		System.out.println("Running testWithAllConstraintSearchResultinJSON");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "appservicesConstraintCombinationOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/all-constraint-json/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/all-constraint-json/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/all-constraint-json/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/all-constraint-json/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/all-constraint-json/", metadataHandle5, "XML");
+	    
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+		
+		// write the files
+		BufferedReader docStream = new BufferedReader(new FileReader("src/junit/com/marklogic/javaclient/queryoptions/" + queryOptionName));
+		handle.set(docStream);
+		
+		// write the query options to the database
+		optionsMgr.writeOptions(queryOptionName, handle);		    
+
+		System.out.println("Write " + queryOptionName + " to database");	
+		
+		// read query option
+		InputStreamHandle readHandle = new InputStreamHandle();
+		readHandle.setFormat(Format.JSON);
+		optionsMgr.readOptions(queryOptionName, readHandle);
+		
+		InputStream output = readHandle.get();
+				
+		// create handle to write back option in json
+		String queryOptionNameJson = queryOptionName.replaceAll(".xml", ".json");
+		InputStreamHandle writeHandle = new InputStreamHandle();
+		writeHandle.set(output);
+		writeHandle.setFormat(Format.JSON);
+		optionsMgr.writeOptions(queryOptionNameJson, writeHandle);
+		System.out.println("Write " + queryOptionNameJson + " to database");
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionNameJson);
+		querydef.setCriteria("(coll:set1 AND coll:set5) AND -intitle:memex AND (pop:high OR pop:medium) AND price:low AND id:**11 AND date:2005-01-01 AND (para:Bush AND -para:memex)");
+
+		// create handle
+		StringHandle resultsHandle = new StringHandle();
+		resultsHandle.setFormat(Format.JSON);
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		String resultString = resultsHandle.get();
+		
+		boolean isTotalCorrect = resultString.contains("\"total\":1");
+		boolean isUriCorrect = resultString.contains("\"uri\":\"/all-constraint-json/constraint1.xml\"");
+		boolean isTitleCorrect = resultString.contains("Vannevar Bush");
+		assertTrue("Returned total document is incorrect", isTotalCorrect);
+		assertTrue("Returned document URI is incorrect", isUriCorrect);
+		assertTrue("Returned document title is incorrect", isTitleCorrect);
+				
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnProperties.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnProperties.java
new file mode 100644
index 000000000..8c6374a7d
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOnProperties.java
@@ -0,0 +1,333 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.*;
+
+import java.util.Calendar;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+
+import com.marklogic.client.document.XMLDocumentManager;
+
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.MatchLocation;
+import com.marklogic.client.query.MatchSnippet;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+
+public class TestSearchOnProperties extends BasicJavaClientREST {
+
+	private static String dbName = "SearchPropsDB";
+	private static String [] fNames = {"SearchPropsDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+		setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOnProperties() throws IOException
+	{
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create the query options
+		StringBuilder builder = new StringBuilder();
+		builder.append("\n");	
+		builder.append("\n");
+		builder.append("properties\n");
+		builder.append("\n");
+		
+		// initialize a handle with the query options
+		StringHandle writeHandle = new StringHandle(builder.toString());
+				
+		// write the query options to the database
+		optionsMgr.writeOptions("propSearchOpt", writeHandle);
+		
+		// acquire the content 
+		File file = new File("xml-with-props.xml");
+		file.delete();
+		boolean success = file.createNewFile();
+		if(success)
+			System.out.println("New file created on " + file.getAbsolutePath());
+		else
+			System.out.println("Cannot create file");
+		
+		BufferedWriter out = new BufferedWriter(new FileWriter(file));
+		String content = 
+				"\n" +
+				"\n" +
+				  "\n" +
+				    "Lisbon\n" +
+					"Portugal\n" +
+			      "\n" +
+				  "\n" +
+					"Madrid\n" +
+					"Spain\n" +
+				  "\n" +
+				"";
+		out.write(content);
+	    out.close();
+	    
+	    // create a manager for XML documents
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = "/searchOnProps/"+file.getPath();
+
+	    // create a handle on the content
+	    FileHandle contentHandle = new FileHandle(file);
+	    contentHandle.set(file);
+	    
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    metadataHandle.getProperties().put("reviewed", true);
+	    metadataHandle.getProperties().put("notes", "embarcadero");
+	    metadataHandle.getProperties().put("number", 1234);
+	    metadataHandle.getProperties().put("longnumber", 1234.455);
+	    metadataHandle.getProperties().put("date", Calendar.getInstance());
+	    
+	    // write the document content
+	    docMgr.write(docId, metadataHandle, contentHandle);
+	    
+	    System.out.println("Write " + docId + " to database");
+	    
+	    DOMHandle readHandle = new DOMHandle();
+	    
+	    // read the metadata
+	    docMgr.read(docId, metadataHandle, readHandle);
+	    
+	    // create a manager for searching
+	    QueryManager queryMgr = client.newQueryManager();
+	    
+	    // create a search definition
+	 	StringQueryDefinition queryDef = queryMgr.newStringDefinition("propSearchOpt");
+	 	queryDef.setCriteria("embarcadero");
+	 		
+	    // create a handle for the search results
+	 	SearchHandle resultsHandle = new SearchHandle();
+
+	 	// run the search
+	 	queryMgr.search(queryDef, resultsHandle);
+
+	 	long totalResults = resultsHandle.getTotalResults();
+	    assertEquals("Total results difference", 1, totalResults);
+		
+		// iterate over the result documents
+		MatchDocumentSummary[] docSummaries = resultsHandle.getMatchResults();
+		
+		int docSummaryLength = docSummaries.length;
+	    assertEquals("Document summary list difference", 1, docSummaryLength);
+
+		for (MatchDocumentSummary docSummary: docSummaries) {
+			String uri = docSummary.getUri();
+			
+			// iterate over the match locations within a result document
+			MatchLocation[] locations = docSummary.getMatchLocations();
+		    assertEquals("Document location difference", "/searchOnProps/"+file.getPath(), uri);
+		
+			for (MatchLocation location: locations) {
+				
+				// iterate over the snippets at a match location
+				for (MatchSnippet snippet : location.getSnippets()) {
+					String highlightedText = "";
+					boolean isHighlighted = snippet.isHighlighted();
+					if(isHighlighted)
+						highlightedText = highlightedText + "[";
+						highlightedText = highlightedText + snippet.getText();
+						highlightedText = highlightedText + "]";
+					
+					assertEquals("Document highlight snippet difference", "[embarcadero]", highlightedText);
+				}
+			}	 	
+		}   
+	    
+		// release the client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOnPropertiesFragment() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchOnPropertiesFragment");
+		
+		String filename1 = "property1.xml";
+		String filename2 = "property2.xml";
+		String filename3 = "property3.xml";
+		String queryOptionName = "propertiesSearchWordOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+
+	    // set metadata properties
+	    metadataHandle1.getProperties().put("city", "Tokyo");
+	    metadataHandle2.getProperties().put("city", "Shanghai");
+	    metadataHandle3.getProperties().put("city", "Tokyo");
+	    	    
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/properties-search/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/properties-search/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/properties-search/", metadataHandle3, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("city-property:Shanghai");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/properties-search/property2.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOnPropertiesBucket() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchOnPropertiesBucket");
+		
+		String filename1 = "property1.xml";
+		String filename2 = "property2.xml";
+		String filename3 = "property3.xml";
+		String queryOptionName = "propertiesSearchWordOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+
+	    // set metadata properties
+	    metadataHandle1.getProperties().put("popularity", 5);
+	    metadataHandle2.getProperties().put("popularity", 9);
+	    metadataHandle3.getProperties().put("popularity", 1);
+	    	    
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/properties-search/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/properties-search/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/properties-search/", metadataHandle3, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:medium");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/properties-search/property1.xml", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+		assertXpathEvaluatesTo("/properties-search/property2.xml", "string(//*[local-name()='result'][2]//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchOnPropertiesBucketAndWord() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSearchOnPropertiesBucketAndWord");
+		
+		String filename1 = "property1.xml";
+		String filename2 = "property2.xml";
+		String filename3 = "property3.xml";
+		String queryOptionName = "propertiesSearchWordOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+	    // create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+
+	    // set metadata properties
+	    metadataHandle1.getProperties().put("popularity", 5);
+	    metadataHandle2.getProperties().put("popularity", 9);
+	    metadataHandle3.getProperties().put("popularity", 1);
+	    metadataHandle1.getProperties().put("city", "Shanghai is a good one");
+	    metadataHandle2.getProperties().put("city", "Tokyo is hot in the summer");
+	    metadataHandle3.getProperties().put("city", "The food in Seoul is similar in Shanghai");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/properties-search/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/properties-search/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/properties-search/", metadataHandle3, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:medium AND city-property:Shanghai");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/properties-search/property1.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOptions.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOptions.java
new file mode 100644
index 000000000..2915448ed
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchOptions.java
@@ -0,0 +1,302 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.QueryManager.QueryView;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+import com.marklogic.client.io.DocumentMetadataHandle.Capability;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathNotExists;
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathExists;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestSearchOptions extends BasicJavaClientREST {
+
+
+	private static String dbName = "TestSearchOptionsDB";
+	private static String [] fNames = {"TestSearchOptionsDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testReturnResultsFalse() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testReturnResultsFalse");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "searchReturnResultsFalseOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-results-false/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("intitle:1945");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathNotExists("//*[local-name()='result']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSetViewMetadata() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSetViewMetadata");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "setViewOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
+	    
+	    // put metadata
+	    metadataHandle.getCollections().addAll("my-collection");
+	    metadataHandle.getCollections().addAll("another-collection");
+	    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
+		
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-setview-meta/", metadataHandle, "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		queryMgr.setView(QueryView.METADATA);
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathExists("//*[local-name()='metrics']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSetViewResults() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSetViewResults");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "setViewOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-setview-results/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		queryMgr.setView(QueryView.RESULTS);
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathExists("//*[local-name()='result']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSetViewFacets() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSetViewFacets");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "setViewOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-setview-facets/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		queryMgr.setView(QueryView.FACETS);
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathExists("//*[local-name()='facet']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSetViewDefault() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSetViewDefault");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "setViewOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-setview-all/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		queryMgr.setView(QueryView.DEFAULT);
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathExists("//*[local-name()='result']", resultDoc);
+		assertXpathExists("//*[local-name()='facet']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+		
+
+@SuppressWarnings("deprecation")
+@Test	public void testSetViewAll() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testSetViewAll");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "setViewOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/return-setview-all/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		queryMgr.setView(QueryView.ALL);
+		
+		// create query def
+		StringQueryDefinition querydef = queryMgr.newStringDefinition(queryOptionName);
+		querydef.setCriteria("pop:high");
+
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(querydef, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("3", "string(//*[local-name()='response']//@*[local-name()='total'])", resultDoc);
+		assertXpathExists("//*[local-name()='result']", resultDoc);
+		assertXpathExists("//*[local-name()='facet']", resultDoc);
+		assertXpathExists("//*[local-name()='metrics']", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static  void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSearchSuggestion.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchSuggestion.java
new file mode 100644
index 000000000..ec9ddb990
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSearchSuggestion.java
@@ -0,0 +1,300 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.SuggestDefinition;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import org.junit.*;
+public class TestSearchSuggestion extends BasicJavaClientREST {
+
+	private static String dbName = "SearchSuggestionDB";
+	private static String [] fNames = {"SearchSuggestionDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	
+	  setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	  addRangeElementIndex(dbName, "string", "http://action/", "title", "http://marklogic.com/collation/");
+	  addRangeElementIndex(dbName, "string", "http://noun/", "title", "http://marklogic.com/collation/");
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestion() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestion");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "suggestionOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition("V", queryOptionName);
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("Vannevar Bush"));
+		assertTrue("suggestion is wrong", suggestions[1].contains("Vannevar served"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionWithSettersAndQuery() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionWithSettersAndQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "suggestionOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition();
+		def.setOptionsName(queryOptionName);
+		def.setStringCriteria("V");
+		def.setQueryStrings("policymaker");
+		def.setLimit(2);
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("Vannevar served"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionMultiByte() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionMultiByte");
+		
+		String[] filenames = {"multibyte1.xml", "multibyte2.xml", "multibyte3.xml"};
+		String queryOptionName = "suggestionOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition("上海", queryOptionName);
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("上海"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionOnAttribute() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionOnAttribute");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "suggestionOpt2.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition("12", queryOptionName);
+		//SuggestDefinition def = queryMgr.newSuggestDefinition();
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("12.34"));
+		assertTrue("suggestion is wrong", suggestions[1].contains("123.45"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionWithNS() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionWithNS");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "suggestionOpt3.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition("2005-01-01", queryOptionName);
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("2005-01-01"));
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionWithNSNonDefault() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionWithNSNonDefault");
+		
+		String[] filenames = {"suggestion1.xml"};
+		String queryOptionName = "suggestionOpt4.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		//SuggestDefinition def = queryMgr.newSuggestDefinition();
+		SuggestDefinition def = queryMgr.newSuggestDefinition();
+		def.setOptionsName(queryOptionName);
+		def.setStringCriteria("noun:a");
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("noun:actor"));
+		assertTrue("suggestion is wrong", suggestions[1].contains("noun:actress"));
+		assertTrue("suggestion is wrong", suggestions[2].contains("noun:apricott"));
+		
+		// release client
+		client.release();		
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testSearchSuggestionWithNSDefault() throws FileNotFoundException
+	{	
+		System.out.println("Running testSearchSuggestionWithNSDefault");
+		
+		String[] filenames = {"suggestion1.xml"};
+		String queryOptionName = "suggestionOpt4.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/ss/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		SuggestDefinition def = queryMgr.newSuggestDefinition();
+		def.setOptionsName(queryOptionName);
+		def.setStringCriteria("a");
+		
+		String[] suggestions = queryMgr.suggest(def);
+			
+		for(int i = 0; i < suggestions.length; i++)
+		{
+			System.out.println(suggestions[i]);
+		}
+		
+		assertTrue("suggestion is wrong", suggestions[0].contains("act"));
+		assertTrue("suggestion is wrong", suggestions[1].contains("acting"));
+		
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestServerAssignedDocumentURI.java b/test-complete/src/test/java/com/marklogic/javaclient/TestServerAssignedDocumentURI.java
new file mode 100644
index 000000000..db8bae868
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestServerAssignedDocumentURI.java
@@ -0,0 +1,305 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.ResourceNotFoundException;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.Transaction;
+import com.marklogic.client.admin.TransformExtensionsManager;
+import com.marklogic.client.document.DocumentDescriptor;
+import com.marklogic.client.document.DocumentUriTemplate;
+import com.marklogic.client.document.ServerTransform;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestServerAssignedDocumentURI extends BasicJavaClientREST {
+	
+	private static String dbName = "TestServerAssignedDocumentUriDB";
+	private static String [] fNames = {"TestServerAssignedDocumentUri-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testCreate()
+	{
+		System.out.println("Running testCreate");
+		
+		String filename = "flipper.xml";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+				
+		// create template
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("xml");
+		template.withDirectory("/mytest/create/");
+		
+		// get the file
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create doc
+		DocumentDescriptor desc = docMgr.create(template, handle);
+		
+		// get the uri
+		String docId = desc.getUri();
+		System.out.println(docId);
+		
+		String content = docMgr.read(desc, new StringHandle()).get();
+		System.out.println(content);
+		
+		assertTrue("document is not created", content.contains("Flipper"));
+				
+	    // release the client
+	    client.release();
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testCreateMultibyte()
+	{
+		System.out.println("Running testCreateMultibyte");
+		
+		String filename = "flipper.xml";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+				
+		// create template
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("xml");
+		template.withDirectory("/里/里/");
+		
+		// get the file
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		String content = null;
+		try {
+		// create doc
+		DocumentDescriptor desc = docMgr.create(template, handle);
+		
+		// get the uri
+		String docId = desc.getUri();
+		System.out.println(docId);
+		
+		content = docMgr.read(desc, new StringHandle()).get();
+		System.out.println(content);
+		
+		assertTrue("document is not created", content.contains("Flipper"));
+		}catch(ResourceNotFoundException e){
+			System.out.println("Because of Special Characters in uri'/é??/é??/10455375835218157514.xml'it is throwing exception");
+		}
+	    // release the client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testCreateInvalidURI() // should be failed
+	{
+		System.out.println("Running testCreateInvalidURI");
+		
+		String filename = "flipper.xml";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+				
+		// create template
+		try{
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("/");
+		template.withDirectory("/mytest/create/");
+		
+		// get the file
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create doc
+		DocumentDescriptor desc = docMgr.create(template, handle);
+		
+		// get the uri
+		String docId = desc.getUri();
+		System.out.println(docId);
+		}
+		catch(IllegalArgumentException i){
+			i.printStackTrace();
+			System.out.println("Expected Output");
+		}
+	    // release the client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testCreateInvalidDirectory() // Should be failed
+	{
+		System.out.println("Running testCreateInvalidDirectory");
+		
+		String filename = "flipper.xml";
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+			try{
+		// create template
+		DocumentUriTemplate template = docMgr.newDocumentUriTemplate("xml");
+		template.withDirectory("/:?#[]@/");
+		
+		// get the file
+		File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename);
+
+		// create a handle on the content
+		FileHandle handle = new FileHandle(file);
+		handle.set(file);
+		
+		// create doc
+		DocumentDescriptor desc = docMgr.create(template, handle);
+		
+		// get the uri
+		String docId = desc.getUri();
+		System.out.println(docId);
+			}
+			catch(IllegalArgumentException i){
+				i.printStackTrace();
+				assertTrue("Expected error didnt came up",i.toString().contains("Directory is not valid: /:?#[]@/"));
+			}
+	    // release the client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testCreateWithTransformerTxMetadata() throws TransformerException, ParserConfigurationException, SAXException, IOException
+	{	
+		System.out.println("Running testCreateWithTransformerTxMetadata");
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// get the doc
+		Source source = new StreamSource("src/test/java/com/marklogic/javaclient/data/employee.xml");
+		
+		// get the xsl
+		File file = new File("src/test/java/com/marklogic/javaclient/data/employee-stylesheet.xsl");
+		
+		String xsl = convertFileToString(file);
+		
+		// create transform
+		TransformExtensionsManager extensionMgr = client.newServerConfigManager().newTransformExtensionsManager();
+		extensionMgr.writeXSLTransform("somename", new StringHandle().with(xsl));
+		ServerTransform transform = new ServerTransform("somename");
+		
+		// release rest-admin client
+		client.release();
+		
+		// connect the rest-writer client
+		DatabaseClient client1 = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// create a doc manager
+	    XMLDocumentManager docMgr = client1.newXMLDocumentManager();
+	    
+		// create template
+	    DocumentUriTemplate template = docMgr.newDocumentUriTemplate("xml");
+		template.withDirectory("/mytest/create/transformer/");
+	 	    
+	    // create a handle on the content
+	    SourceHandle handle = new SourceHandle();
+	    handle.set(source);
+	    
+		// get the original metadata
+		Document docMetadata = getXMLMetadata("metadata-original.xml");
+		
+		// create handle to write metadata
+		DOMHandle writeMetadataHandle = new DOMHandle();
+		writeMetadataHandle.set(docMetadata);
+	    
+	    // create transaction
+	    Transaction transaction = client1.openTransaction();
+	    
+	    // create doc
+	    DocumentDescriptor desc = docMgr.create(template, writeMetadataHandle, handle, transform, transaction);
+	    
+		// get the uri
+		String docId = desc.getUri();
+		System.out.println(docId);
+		
+		System.out.println("Before commit:");
+	    
+		String exception = "";
+		try
+		{
+			String content = docMgr.read(desc, new StringHandle()).get();
+			System.out.println(content);
+		} catch (Exception e) 
+		
+		{
+			System.out.println(e);
+			exception = e.toString();
+		}
+		
+		String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT";
+		assertTrue("Exception is not thrown", exception.contains(expectedException));
+
+		System.out.println("After commit:");
+		transaction.commit();
+		
+		String content1 = docMgr.read(desc, new StringHandle()).get();
+		System.out.println(content1);
+		
+		assertTrue("document is not created", content1.contains("firstname"));
+		
+	    // read metadata
+	    String metadataContent = docMgr.readMetadata(docId, new StringHandle()).get();
+	    System.out.println(metadataContent);
+	    
+	    assertTrue("metadata is not created", metadataContent.contains("MarkLogic"));
+			    
+	    // release client
+	    client1.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestSourceHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestSourceHandle.java
new file mode 100644
index 000000000..9f92b2b8d
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestSourceHandle.java
@@ -0,0 +1,114 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.InputSourceHandle;
+import com.marklogic.client.io.InputStreamHandle;
+import com.marklogic.client.io.SourceHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestSourceHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "SourceHandleDB";
+	private static String [] fNames = {"SourceHandleDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static  void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException, TransformerException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-sourcehandle/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingInputStreamHandle(client, filename, uri, "XML");
+				
+		// read docs
+		SourceHandle contentHandle = readDocumentUsingSourceHandle(client, uri + filename, "XML");
+		
+		// get the contents
+		Source fileRead = contentHandle.get();
+		
+		String readContent = convertSourceToString(fileRead);
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    SourceHandle updateHandle = readDocumentUsingSourceHandle(client, uri + filename, "XML");
+	 
+	    // get the contents
+	    Source fileReadUpdate = updateHandle.get();
+	 	
+	    String readContentUpdate = convertSourceToString(fileReadUpdate);
+
+		// get xml document for expected result
+		Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+		// convert actual string to xml doc
+		Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+		// delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+		// read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	InputStreamHandle deleteHandle = readDocumentUsingInputStreamHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "Could not read non-existent document";
+	    boolean documentIsDeleted = exception.contains(expectedException);
+	    assertTrue("Document is not deleted", documentIsDeleted);
+	    
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+		
+	}
+}
\ No newline at end of file
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneGeoQuery.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneGeoQuery.java
new file mode 100644
index 000000000..90efd977a
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneGeoQuery.java
@@ -0,0 +1,477 @@
+package com.marklogic.javaclient;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder.FragmentScope;
+import org.junit.*;
+public class TestStandaloneGeoQuery extends BasicJavaClientREST {
+
+	private static String dbName = "TestStandaloneGeoQueryDB";
+	private static String [] fNames = {"TestStandaloneGeoQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug22184() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testBug22184");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoElement(qb.element("g-elem-pair")));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		String result = convertXMLDocumentToString(resultDoc);
+		System.out.println(result);
+		assertTrue("Results are not proper", result.contains("start=\"1\" total=\"5\""));
+		//assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoElemQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoElemQuery");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoElement(qb.element("g-elem-pair")),qb.point(12, 5));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoElemPairQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoElemPairQuery");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoElementPair(qb.element("g-elem-pair"), qb.element("lat"), qb.element("long")), qb.point(12, 5));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoElemPairQueryEnhanced() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoElemPairQueryEnhanced");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		//StructuredQueryDefinition t = qb.geospatial(qb.geoElementPair(qb.element("g-elem-pair"), qb.element("lat"), qb.element("long")), qb.point(12, 5));
+		String[] options = {"coordinate-system=wgs84","units=miles"};
+		StructuredQueryDefinition t = qb.geospatial(qb.geoElementPair(qb.element("g-elem-pair"), qb.element("lat"), qb.element("long")), FragmentScope.DOCUMENTS, options, qb.point(12, 5));
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoElemChildQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoElemQuery");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoElement(qb.element("g-elem-child-parent"), qb.element("g-elem-child-point")), qb.point(12, 5));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test public void testStandaloneGeoElemChildQueryEnhanced() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+{	
+	System.out.println("Running testStandaloneGeoElemQueryEnhanced");
+	
+	String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+	DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+	
+	// set query option validation to true
+	ServerConfigurationManager srvMgr = client.newServerConfigManager();
+	srvMgr.readConfiguration();
+	srvMgr.setQueryOptionValidation(true);
+	srvMgr.writeConfiguration();
+			
+	// write docs
+	for(String filename : filenames)
+	{
+		writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+	}
+	
+	QueryManager queryMgr = client.newQueryManager();
+	
+	// create query def
+	StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+	String[] options = {"coordinate-system=wgs84","units=miles"};
+	StructuredQueryDefinition t = qb.geospatial(qb.geoElement(qb.element("g-elem-child-parent"), qb.element("g-elem-child-point")), FragmentScope.DOCUMENTS, options, qb.point(12, 5));
+	
+	// create handle
+	DOMHandle resultsHandle = new DOMHandle();
+	queryMgr.search(t, resultsHandle);
+	
+	// get the result
+	Document resultDoc = resultsHandle.get();
+	System.out.println(convertXMLDocumentToString(resultDoc));
+	
+	assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+	//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+    		
+	// release client
+	client.release();		
+}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoAttrPairQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoAttrPairQuery");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoAttributePair(qb.element("g-attr-pair"), qb.attribute("lat"), qb.attribute("long")), qb.point(12, 5));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoAttrPairQueryBox() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoAttrPairQueryBox");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml","element-attribute-pair-geo-data.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.geospatial(qb.geoAttributePair(qb.element("point"), qb.attribute("latitude"), qb.attribute("longitude")), qb.box(52,172,55,-163));
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Results of Box :"+ convertXMLDocumentToString(resultDoc));
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertTrue("Result returned is wrong", convertXMLDocumentToString(resultDoc).contains("beijing city in china bangkok city in thailand norh pole place where Santa lives"));
+		
+		//Circle Query
+		QueryManager queryMgr1 = client.newQueryManager();
+		// create query def
+		StructuredQueryBuilder qb1 = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t1 = qb1.geospatial(qb1.geoAttributePair(qb1.element("point"), qb1.attribute("latitude"), qb1.attribute("longitude")), qb1.circle(qb1.point(53.90, -166.70),3));
+		// create handle
+		DOMHandle resultsHandle1 = new DOMHandle();
+		queryMgr1.search(t1, resultsHandle1);
+		// get the result
+		Document resultDoc1 = resultsHandle1.get();
+		System.out.println("Results of Circle :"+ convertXMLDocumentToString(resultDoc1));
+		assertTrue("Result returned is wrong", convertXMLDocumentToString(resultDoc1).contains("beijing city in china bangkok city in thailand norh pole place where Santa lives"));
+		//Polygon Query
+		QueryManager queryMgr2 = client.newQueryManager();
+		// create query def
+		StructuredQueryBuilder qb2 = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t2 = qb2.geospatial(qb2.geoAttributePair(qb2.element("point"), qb2.attribute("latitude"), qb2.attribute("longitude")), qb2.polygon(qb2.point(54,-165),qb2.point(52,-167),qb2.point(53,167),qb2.point(54,-165)));
+		// create handle
+		DOMHandle resultsHandle2 = new DOMHandle();
+		queryMgr2.search(t2, resultsHandle2);
+		// get the result
+		Document resultDoc2 = resultsHandle2.get();
+		System.out.println("Results of Polygon :"+ convertXMLDocumentToString(resultDoc2));
+		assertTrue("Result returned is wrong", convertXMLDocumentToString(resultDoc2).contains("beijing city in china bangkok city in thailand norh pole place where Santa lives"));
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneGeoAttrPairQueryWithOrAndNear() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneGeoAttrPairQueryWithOr");
+		
+		String[] filenames = {"geo-constraint1.xml", "geo-constraint2.xml", "geo-constraint3.xml", "geo-constraint4.xml", "geo-constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-geo-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create OR query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition x = qb.geospatial(qb.geoAttributePair(qb.element("g-attr-pair"), qb.attribute("lat"), qb.attribute("long")), qb.point(12, 5));
+		StructuredQueryDefinition y = qb.word(qb.element("name"), "karl_gale");
+		StructuredQueryDefinition z = qb.or(x, y);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(z, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Result of OR Query"+convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		
+		// create AND query def
+		StructuredQueryDefinition p = qb.geospatial(qb.geoAttributePair(qb.element("g-attr-pair"), qb.attribute("lat"), qb.attribute("long")), qb.point(12, 6));
+		StructuredQueryDefinition q = qb.word(qb.element("name"), "karl_gale");
+		StructuredQueryDefinition r = qb.and(p,q);
+		
+		// create handle
+		DOMHandle resultsHandle1 = new DOMHandle();
+		queryMgr.search(r, resultsHandle1);
+		
+		// get the result
+		Document resultDoc1 = resultsHandle1.get();
+		System.out.println("Results of AND Query"+convertXMLDocumentToString(resultDoc1));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		// release client
+		// create NEAR query def
+		StructuredQueryDefinition c = qb.near(z,r);
+		
+		// create handle
+		DOMHandle resultsHandle2 = new DOMHandle();
+		queryMgr.search(c, resultsHandle2);
+		
+		// get the result
+		Document resultDoc2 = resultsHandle2.get();
+		System.out.println("Results of NEAR Query"+convertXMLDocumentToString(resultDoc2));
+		
+
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneQuery.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneQuery.java
new file mode 100644
index 000000000..a4a284241
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStandaloneQuery.java
@@ -0,0 +1,477 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryBuilder.FragmentScope;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+
+import org.junit.*;
+public class TestStandaloneQuery extends BasicJavaClientREST {
+
+	private static String dbName = "TestStandaloneQueryDB";
+	private static String [] fNames = {"TestStandaloneQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneWordQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneWordQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.word(qb.element("id"), "0026");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Output of Search : "+convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='highlight'][1]//*[local-name()='id'])", resultDoc);
+	    assertTrue("Proper result is not returned :", convertXMLDocumentToString(resultDoc).contains("0026"));	
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneWordQueryEnhanced() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneWordQueryEnhanced");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		//StructuredQueryDefinition t = qb.word(qb.element(new QName("http://cloudbank.com", "price")), "0026");
+		String[] options = {"case-insensitive","stemmed","unwildcarded"};
+		StructuredQueryDefinition t = qb.word(qb.elementAttribute(qb.element(new QName("http://cloudbank.com", "price")), qb.attribute("amt")), FragmentScope.DOCUMENTS, options ,.025 , "123.45");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		String output=convertXMLDocumentToString(resultDoc);
+		System.out.println(output);
+		System.out.println("Search Result : " + resultDoc.getDocumentURI());
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertTrue("Results are not proper",output.contains("uri=\"/standalone-query/constraint5.xml\"") );    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQuery");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            StructuredQueryDefinition t = qb.range(qb.element("popularity"), "xs:integer", Operator.GE, 4);
+
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQueryEnhanced() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQueryEnhanced");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            String collation = "http://marklogic.com/collation/en";
+            StructuredQueryDefinition t =qb.range(qb.element("popularity"), "xs:integer", collation, Operator.GE, 4);
+
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQueryEnhanced1() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQueryEnhanced1");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            String[] options = {"uncached","min-occurs=2"};
+            StructuredQueryDefinition t =qb.range(qb.element("popularity"), "xs:integer", options, Operator.LE, 4);
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQueryEnhanced2() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQueryEnhanced2");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            String[] options = {"uncached","min-occurs=2"};
+            String collation = "http://marklogic.com/collation/en";
+            StructuredQueryDefinition t =qb.range(qb.element("popularity"), "xs:integer", collation, options, Operator.LT, 4);        
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQueryEnhanced3() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQueryEnhanced3");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            String collation = "http://marklogic.com/collation/en";
+            StructuredQueryDefinition t =qb.range(qb.element("popularity"), "xs:integer", collation, FragmentScope.DOCUMENTS, Operator.GT, 4);
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("3", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneRangeQueryEnhanced4() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+    {
+            System.out.println("Running testStandaloneRangeQueryEnhanced4");
+
+            String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+            DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+
+            // set query option validation to true
+            ServerConfigurationManager srvMgr = client.newServerConfigManager();
+            srvMgr.readConfiguration();
+            srvMgr.setQueryOptionValidation(true);
+            srvMgr.writeConfiguration();
+
+            // write docs
+            for(String filename : filenames)
+            {
+                    writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+            }
+
+            QueryManager queryMgr = client.newQueryManager();
+
+            // create query def
+            StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+            String collation = "http://marklogic.com/collation/en";
+            String[] options = {"uncached","min-occurs=2"};
+
+            StructuredQueryDefinition t =qb.range(qb.element("popularity"), "xs:integer", collation, FragmentScope.DOCUMENTS, options, Operator.NE, 4);
+            // create handle
+            DOMHandle resultsHandle = new DOMHandle();
+            queryMgr.search(t, resultsHandle);
+
+            // get the result
+            Document resultDoc = resultsHandle.get();
+            System.out.println(convertXMLDocumentToString(resultDoc));
+
+            assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+            //assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+
+            // release client
+            client.release();
+    }
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneValueQueryOnAttribute() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneValueQueryOnAttribute");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		StructuredQueryDefinition t = qb.value(qb.elementAttribute(qb.element(new QName("http://cloudbank.com", "price")), qb.attribute("amt")), "0.1");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStandaloneValueQueryOnAttributeEnhanced() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStandaloneValueQueryOnAttributeEnhanced");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/standalone-query/", "XML");
+		}
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder();
+		//StructuredQueryDefinition t = qb.value(qb.elementAttribute(qb.element(new QName("http://cloudbank.com", "price")), qb.attribute("amt")), "0.1");
+		String[] options = {"case-insensitive","stemmed","unwildcarded"};
+		StructuredQueryDefinition t1 = qb.value(qb.elementAttribute(qb.element(new QName("http://cloudbank.com", "price")), qb.attribute("amt")), FragmentScope.DOCUMENTS, options , 3.0, "123.45");
+	
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t1, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		String output = convertXMLDocumentToString(resultDoc);
+		System.out.println(output);
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertTrue("The result is not proper", output.contains("/standalone-query/constraint5.xml"));
+		// release client
+		client.release();		
+	}
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStringHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStringHandle.java
new file mode 100644
index 000000000..2082c2e71
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStringHandle.java
@@ -0,0 +1,275 @@
+package com.marklogic.javaclient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.StringHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+public class TestStringHandle extends BasicJavaClientREST {
+	
+	private static String dbName = "StringDB";
+	private static String [] fNames = {"StringDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException
+	{	
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-string/";
+		
+		System.out.println("Running testXmlCRUD");
+				
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		 writeDocumentUsingStringHandle(client, filename, uri, "XML");
+				
+		// read docs
+		StringHandle contentHandle = readDocumentUsingStringHandle(client, uri + filename, "XML");
+		
+		// get the contents
+	//	File fileRead = contentHandle.get();
+		
+		String readContent = contentHandle.get();
+
+		// get xml document for expected result
+		Document expectedDoc = expectedXMLDocument(filename);
+		
+		// convert actual string to xml doc
+		Document readDoc = convertStringToXMLDocument(readContent);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDoc, readDoc);
+				
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "xml-updated-test.xml";
+	    updateDocumentUsingStringHandle(client, updateFilename, uri + filename, "XML");
+	    
+	    // read the document
+	    StringHandle updateHandle = readDocumentUsingStringHandle(client, uri + filename, "XML");
+	 
+	    // get the contents
+	    String readContentUpdate = updateHandle.get();
+	 	
+//	    String readContentUpdate = convertFileToString(fileReadUpdate);
+
+	    // get xml document for expected result
+	    Document expectedDocUpdate = expectedXMLDocument(updateFilename);
+		
+	    // convert actual string to xml doc
+	    Document readDocUpdate = convertStringToXMLDocument(readContentUpdate);
+	    	    
+	    assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate);
+	 		 	
+	    // delete the document
+	    deleteDocument(client, uri + filename, "XML");
+	    
+	    // read the deleted document
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "XML");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+            String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-xml-string/xml-original-test.xml";
+	    assertEquals("Document is not deleted", expectedException, exception);
+	    
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "XML"));
+	    
+	    // release client
+	    client.release();
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testTextCRUD() throws IOException
+	{	
+	    String filename = "text-original.txt";
+	    String uri = "/write-text-stringhandle/";
+		
+	    System.out.println("Running testTextCRUD");
+		
+	    // connect the client
+	    DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+	    // write docs
+	    writeDocumentUsingStringHandle(client, filename, uri, "Text");
+				
+	    // read docs
+	    StringHandle contentHandle = readDocumentUsingStringHandle(client, uri + filename, "Text");
+		
+	    // get the contents
+//	    File fileRead = contentHandle.get();
+		
+	    String readContent = contentHandle.get();
+		
+	    String expectedContent = "hello world, welcome to java API";
+						
+	    assertEquals("Write Text difference", expectedContent.trim(), readContent.trim());
+
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "text-updated.txt";
+	    updateDocumentUsingStringHandle(client, updateFilename, uri + filename, "Text");
+	    
+	    // read the document
+	    StringHandle updateHandle = readDocumentUsingStringHandle(client, uri + filename, "Text");
+		
+		// get the contents
+//		File fileReadUpdate = updateHandle.get();
+		
+		String readContentUpdate = updateHandle.get();
+		
+		String expectedContentUpdate = "hello world, welcome to java API after new updates";
+		
+		assertEquals("Write Text difference", expectedContentUpdate.trim(), readContentUpdate.toString().trim());
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "Text");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "Text"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "Text");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-text-stringhandle/text-original.txt";
+	    assertEquals("Document is not deleted", expectedException, exception);
+
+		
+		// release client
+		client.release();
+	}
+
+
+@SuppressWarnings("deprecation")
+@Test	public void testJsonCRUD() throws IOException
+	{	
+		String filename = "json-original.json";
+		String uri = "/write-json-stringhandle/";
+		
+		System.out.println("Running testJsonCRUD");
+		
+		ObjectMapper mapper = new ObjectMapper();
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// write docs
+		writeDocumentUsingStringHandle(client, filename, uri, "JSON");
+				
+		// read docs
+		StringHandle contentHandle = readDocumentUsingStringHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+//		File fileRead = contentHandle.get();
+		
+//		JsonNode readContent = mapper.readTree(fileRead);
+                JsonNode readContent = mapper.readValue(contentHandle.get(),JsonNode.class);
+
+				
+		// get expected contents
+		JsonNode expectedContent = expectedJSONDocument(filename);
+				
+		assertTrue("Write JSON document difference", readContent.equals(expectedContent));		
+		
+	    // update the doc
+	    // acquire the content for update
+	    String updateFilename = "json-updated.json";
+	    updateDocumentUsingFileHandle(client, updateFilename, uri + filename, "JSON");
+	    
+	    // read the document
+	    FileHandle updateHandle = readDocumentUsingFileHandle(client, uri + filename, "JSON");
+		
+		// get the contents
+		File fileReadUpdate = updateHandle.get();
+				
+		JsonNode readContentUpdate = mapper.readTree(fileReadUpdate);
+		
+		// get expected contents
+		JsonNode expectedContentUpdate = expectedJSONDocument(updateFilename);
+				
+		assertTrue("Write JSON document difference", readContentUpdate.equals(expectedContentUpdate));		
+
+		// delete the document
+	    deleteDocument(client, uri + filename, "JSON");
+
+		// read the deleted document
+	    //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "JSON"));
+	    
+	    String exception = "";
+	    try
+	    {
+	    	FileHandle deleteHandle = readDocumentUsingFileHandle(client, uri + filename, "JSON");
+	    } catch (Exception e) { exception = e.toString(); }
+	    
+	    String expectedException = "com.marklogic.client.ResourceNotFoundException: Local message: Could not read non-existent document. Server Message: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist:  category: content message: /write-json-stringhandle/json-original.json";
+	    assertEquals("Document is not deleted", expectedException, exception);
+
+		
+		// release client
+		client.release();
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testBug22356() throws IOException, SAXException, ParserConfigurationException
+	{	
+		System.out.println("Running testBug22356");
+		
+		String filename = "xml-original-test.xml";
+		String uri = "/write-xml-string/";
+		
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+			
+		// read docs
+		StringHandle contentHandle = null;
+		try
+	    {
+		// get the contents
+		String readContent = contentHandle.get();
+	    } 
+		catch (NullPointerException e) { 
+			System.out.println("Null pointer Exception is expected noy an Empty Value");
+			e.toString(); 
+		}
+	    
+        // release client
+	    client.release();
+	}
+	
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+		
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQuery.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQuery.java
new file mode 100644
index 000000000..87646580f
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQuery.java
@@ -0,0 +1,567 @@
+
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.query.StructuredQueryBuilder.Operator;
+import com.marklogic.client.io.DOMHandle;
+import com.marklogic.client.io.DocumentMetadataHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestStructuredQuery extends BasicJavaClientREST {
+
+	private static String dbName = "TestStructuredQueryDB";
+	private static String [] fNames = {"TestStructuredQueryDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass	public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	 setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+@After
+public  void testCleanUp() throws Exception
+{
+	clearDB(8011);
+	System.out.println("Running clear script");
+}	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStructuredQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStructuredQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition t = qb.valueConstraint("id", "0026");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+	    		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testStructuredQueryJSON() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStructuredQueryJSON");
+		
+		String[] filenames = {"constraint1.json", "constraint2.json", "constraint3.json", "constraint4.json", "constraint5.json"};
+		String queryOptionName = "valueConstraintWildCardOpt.json";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query/", "JSON");
+		}
+		setJSONQueryOption(client, queryOptionName);
+//		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create value query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition t = qb.value(qb.jsonProperty("popularity"),"4");
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(t, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/structured-query/constraint2.json", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc);
+	    
+		//create new word query def
+		StructuredQueryDefinition t1 = qb.word(qb.jsonProperty("id"), "0012");
+		// create handle
+		DOMHandle resultsHandle1 = new DOMHandle();
+		queryMgr.search(t1, resultsHandle1);
+		
+		// get the result
+		Document resultDoc1 = resultsHandle1.get();
+		System.out.println(convertXMLDocumentToString(resultDoc1));
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc1);
+		assertXpathEvaluatesTo("/structured-query/constraint2.json", "string(//*[local-name()='result'][1]//@*[local-name()='uri'])", resultDoc1);
+		
+		//create new range word query def
+		StructuredQueryDefinition t2 = qb.range(qb.jsonProperty("price"), "xs:integer", Operator.GE, "0.1");
+		// create handle
+		DOMHandle resultsHandle2 = new DOMHandle();
+		queryMgr.search(t2, resultsHandle2);
+		
+		// get the result
+		Document resultDoc2 = resultsHandle2.get();
+		System.out.println(convertXMLDocumentToString(resultDoc2));
+		assertXpathEvaluatesTo("5", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc2);
+	
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testValueConstraintWildCard() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testValueConstraintWildCard");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition valueConstraintQuery1 = qb.valueConstraint("id", "00*2");
+		StructuredQueryDefinition valueConstraintQuery2 = qb.valueConstraint("id", "0??6");
+		StructuredQueryDefinition orFinalQuery = qb.or(valueConstraintQuery1, valueConstraintQuery2);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(orFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testAndNotQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testAndNotQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query-andnot/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery1 = qb.term("Atlantic");
+		StructuredQueryDefinition termQuery2 = qb.term("Monthly");
+		StructuredQueryDefinition termQuery3 = qb.term("Bush");
+		StructuredQueryDefinition andQuery = qb.and(termQuery1, termQuery2);
+		StructuredQueryDefinition andNotFinalQuery = qb.andNot(andQuery, termQuery3);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(andNotFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0113", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testNearQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testNearQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query-near/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery1 = qb.term("Bush");
+		StructuredQueryDefinition termQuery2 = qb.term("Atlantic");
+		StructuredQueryDefinition nearQuery = qb.near(6, 1.0, StructuredQueryBuilder.Ordering.UNORDERED, termQuery1, termQuery2);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(nearQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0011", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testDirectoryQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDirectoryQuery");
+		
+		String[] filenames1 = {"constraint1.xml", "constraint2.xml", "constraint3.xml"};
+		String[] filenames2 = {"constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename1 : filenames1)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename1, "/dir1/dir2/", "XML");
+		}
+		
+		// write docs
+		for(String filename2 : filenames2)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename2, "/dir3/dir4/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery = qb.term("Memex");
+		StructuredQueryDefinition dirQuery = qb.directory(true, "/dir3/");
+		StructuredQueryDefinition andFinalQuery = qb.and(termQuery, dirQuery);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(andFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testDocumentQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testDocumentQuery");
+		
+		String[] filenames1 = {"constraint1.xml", "constraint2.xml", "constraint3.xml"};
+		String[] filenames2 = {"constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename1 : filenames1)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename1, "/dir1/dir2/", "XML");
+		}
+		
+		// write docs
+		for(String filename2 : filenames2)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename2, "/dir3/dir4/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery = qb.term("Memex");
+		StructuredQueryDefinition docQuery = qb.or(qb.document("/dir1/dir2/constraint2.xml"), qb.document("/dir3/dir4/constraint4.xml"), qb.document("/dir3/dir4/constraint5.xml"));
+		StructuredQueryDefinition andFinalQuery = qb.and(termQuery, docQuery);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(andFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testCollectionQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testCollectionQuery");
+		
+		String filename1 = "constraint1.xml";
+		String filename2 = "constraint2.xml";
+		String filename3 = "constraint3.xml";
+		String filename4 = "constraint4.xml";
+		String filename5 = "constraint5.xml";
+		String queryOptionName = "valueConstraintWildCardOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// create and initialize a handle on the metadata
+	    DocumentMetadataHandle metadataHandle1 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle2 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle3 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle4 = new DocumentMetadataHandle();
+	    DocumentMetadataHandle metadataHandle5 = new DocumentMetadataHandle();
+		
+	    // set the metadata
+	    metadataHandle1.getCollections().addAll("http://test.com/set1");
+	    metadataHandle1.getCollections().addAll("http://test.com/set5");
+	    metadataHandle2.getCollections().addAll("http://test.com/set1");
+	    metadataHandle3.getCollections().addAll("http://test.com/set3");
+	    metadataHandle4.getCollections().addAll("http://test.com/set3/set3-1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set1");
+	    metadataHandle5.getCollections().addAll("http://test.com/set5");
+
+	    // write docs
+	    writeDocumentUsingInputStreamHandle(client, filename1, "/collection-constraint/", metadataHandle1, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename2, "/collection-constraint/", metadataHandle2, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename3, "/collection-constraint/", metadataHandle3, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename4, "/collection-constraint/", metadataHandle4, "XML");
+	    writeDocumentUsingInputStreamHandle(client, filename5, "/collection-constraint/", metadataHandle5, "XML");
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery = qb.term("Memex");
+		StructuredQueryDefinition collQuery = qb.or(qb.collection("http://test.com/set1"), qb.collection("http://test.com/set3"));
+		StructuredQueryDefinition andFinalQuery = qb.and(termQuery, collQuery);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(andFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		//System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testContainerConstraintQuery() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testContainerConstraintQuery");
+		
+		String[] filenames = {"constraint1.xml", "constraint2.xml", "constraint3.xml", "constraint4.xml", "constraint5.xml"};
+		String queryOptionName = "containerConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query-container/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition containerQuery = qb.containerConstraint("title-contain", qb.term("Bush"));
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(containerQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0011", "string(//*[local-name()='result']//*[local-name()='id'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    
+		//String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQueryMildNot.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQueryMildNot.java
new file mode 100644
index 000000000..6b287d182
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredQueryMildNot.java
@@ -0,0 +1,93 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.ServerConfigurationManager;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestStructuredQueryMildNot extends BasicJavaClientREST {
+
+	private static String dbName = "TestStructuredQueryMildNotDB";
+	private static String [] fNames = {"TestStructuredQueryMildNotDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testStructuredQueryMildNot() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testStructuredQueryMildNot");
+		
+		String[] filenames = {"mildnot1.xml"};
+		String queryOptionName = "mildNotOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// set query option validation to true
+		ServerConfigurationManager srvMgr = client.newServerConfigManager();
+		srvMgr.readConfiguration();
+		srvMgr.setQueryOptionValidation(true);
+		srvMgr.writeConfiguration();
+				
+		// write docs
+		for(String filename : filenames)
+		{
+			writeDocumentUsingInputStreamHandle(client, filename, "/structured-query-mild-not/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition termQuery1 = qb.term("summer");
+		StructuredQueryDefinition termQuery2 = qb.term("time");
+		StructuredQueryDefinition notInFinalQuery = qb.notIn(termQuery1, termQuery2);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(notInFinalQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println(convertXMLDocumentToString(resultDoc));
+		
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("0012", "string(//*[local-name()='result'][1]//*[local-name()='id'])", resultDoc);
+		//assertXpathEvaluatesTo("0026", "string(//*[local-name()='result'][2]//*[local-name()='id'])", resultDoc);
+	    //String expectedSearchReport = "(cts:search(fn:collection(), cts:and-query(cts:or-query((cts:element-value-query(fn:QName(\"\", \"id\"), \"00*2\", (\"lang=en\"), 1), cts:element-value-query(fn:QName(\"\", \"id\"), \"0??6\", (\"lang=en\"), 1)), ()), (\"score-logtfidf\"), 1))[1 to 10]";
+		
+		//assertXpathEvaluatesTo(expectedSearchReport, "string(//*[local-name()='report'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredSearchGeo.java b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredSearchGeo.java
new file mode 100644
index 000000000..0a77693ff
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestStructuredSearchGeo.java
@@ -0,0 +1,169 @@
+package com.marklogic.javaclient;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.marklogic.client.query.QueryManager;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.StructuredQueryBuilder;
+import com.marklogic.client.query.StructuredQueryDefinition;
+import com.marklogic.client.util.EditableNamespaceContext;
+import com.marklogic.client.io.DOMHandle;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
+import static org.junit.Assert.*;
+
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.*;
+public class TestStructuredSearchGeo extends BasicJavaClientREST {
+
+	private static String dbName = "TestStructuredSearchGeoDB";
+	private static String [] fNames = {"TestStructuredSearchGeoDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+
+@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServer(dbName, fNames[0], restServerName,8011);
+	  setupAppServicesGeoConstraint(dbName);
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testTestStructuredSearchGeo() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testTestStructuredSearchGeo");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		for(int i = 1; i <= 7; i++)
+		{
+			writeDocumentUsingInputStreamHandle(client, "geo-constraint" + i + ".xml", "/geo-constraint/", "XML");
+		}
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		StructuredQueryDefinition geoElementConstraintQuery = qb.geospatialConstraint("geo-elem", qb.point(12, 5));
+		StructuredQueryDefinition termQuery = qb.term("bill_kara");
+		StructuredQueryDefinition finalOrQuery = qb.or(geoElementConstraintQuery, termQuery);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(finalOrQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		
+		assertXpathEvaluatesTo("2", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		//assertXpathEvaluatesTo("karl_kara 12,5 12,5 12 5", "string(//*[local-name()='result'][1]//*[local-name()='match'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+
+@SuppressWarnings("deprecation")
+@Test	public void testTestStructuredSearchGeoBox() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testTestStructuredSearchGeoBox");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		
+		StructuredQueryDefinition geoElementConstraintQuery = qb.geospatialConstraint("geo-elem-child", qb.box(-12,-5,-11,-4));
+		StructuredQueryDefinition termQuery = qb.term("karl_kara");
+		StructuredQueryDefinition finalAndQuery = qb.and(geoElementConstraintQuery, termQuery);
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(finalAndQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Output : " + convertXMLDocumentToString(resultDoc));
+		assertXpathEvaluatesTo("1", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		assertXpathEvaluatesTo("/geo-constraint/geo-constraint2.xml", "string(//*[local-name()='result']//@*[local-name()='uri'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+
+@SuppressWarnings("deprecation")
+@Test	public void testTestStructuredSearchGeoBoxAndPath() throws IOException, ParserConfigurationException, SAXException, XpathException, TransformerException
+	{	
+		System.out.println("Running testTestStructuredSearchGeoBoxAndPath" + "This test is for Bug : 22071 & 22136");
+		
+		String queryOptionName = "geoConstraintOpt.xml";
+
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+				
+		// write docs
+		loadGeoData();
+		
+		setQueryOption(client, queryOptionName);
+		
+		QueryManager queryMgr = client.newQueryManager();
+		
+		// create query def
+		StructuredQueryBuilder qb = queryMgr.newStructuredQueryBuilder(queryOptionName);
+		
+		StructuredQueryDefinition geoQuery = qb.geospatial(qb.geoPath(qb.pathIndex("/doc/g-elem-point")), qb.box(-12,-5,-11,-4));
+		Collection nameSpaceCollection = qb.getNamespaces().getAllPrefixes();
+		assertEquals("getNamespace failed ",false, nameSpaceCollection.isEmpty());
+		for(String prefix : nameSpaceCollection){
+			System.out.println("Prefixes : "+prefix);
+			System.out.println(qb.getNamespaces().getNamespaceURI(prefix));
+			if (qb.getNamespaces().getNamespaceURI(prefix).contains("http://www.w3.org/2001/XMLSchema"))
+			{
+				EditableNamespaceContext namespaces = new EditableNamespaceContext();
+				namespaces.put("new", "http://www.marklogic.com");
+				qb.setNamespaces(namespaces);
+				System.out.println(qb.getNamespaces().getNamespaceURI("new"));
+			}
+		}
+		
+		// create handle
+		DOMHandle resultsHandle = new DOMHandle();
+		queryMgr.search(geoQuery, resultsHandle);
+		
+		// get the result
+		Document resultDoc = resultsHandle.get();
+		System.out.println("Output : " + convertXMLDocumentToString(resultDoc));
+		assertXpathEvaluatesTo("4", "string(//*[local-name()='result'][last()]//@*[local-name()='index'])", resultDoc);
+		
+		// release client
+		client.release();		
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestTransformXMLWithXSLT.java b/test-complete/src/test/java/com/marklogic/javaclient/TestTransformXMLWithXSLT.java
new file mode 100644
index 000000000..66a105e18
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestTransformXMLWithXSLT.java
@@ -0,0 +1,91 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.Scanner;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.io.SourceHandle;
+import org.junit.*;
+
+public class TestTransformXMLWithXSLT extends BasicJavaClientREST {
+
+
+	@BeforeClass public static void setUp() throws Exception 
+		{
+		  System.out.println("In setup");
+		  setupJavaRESTServerWithDB( "REST-Java-Client-API-Server", 8011);
+		 
+		}
+		
+	@SuppressWarnings("deprecation")
+	@Test	public void testWriteXMLWithXSLTransform() throws TransformerException, FileNotFoundException
+	{	
+		// connect the client
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST);
+		
+		// get the doc
+		Source source = new StreamSource("src/test/java/com/marklogic/javaclient/data/employee.xml");
+		
+		// get the xslt
+		Source xsl = new StreamSource("src/test/java/com/marklogic/javaclient/data/employee-stylesheet.xsl");
+				
+		// create transformer
+		TransformerFactory factory = TransformerFactory.newInstance();
+		Transformer transformer = factory.newTransformer(xsl);
+		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+		
+		// create a doc manager
+	    XMLDocumentManager docMgr = client.newXMLDocumentManager();
+	 
+	    // create an identifier for the document
+	    String docId = "/example/trans/transform.xml";
+	    
+	    // create a handle on the content
+	    SourceHandle handle = new SourceHandle();
+	    handle.set(source);
+	    
+	    // set the transformer
+	    handle.setTransformer(transformer);
+	    
+	    // write the document content
+	    docMgr.write(docId, handle);
+	    
+	    System.out.println("Write " + docId + " to database");
+
+	    // create a handle on the content
+	    FileHandle readHandle = new FileHandle();
+	    
+	    // read the document
+	    docMgr.read(docId, readHandle);
+	    
+	    // access the document content
+	    File fileRead = readHandle.get();
+	    
+	    Scanner scanner = new Scanner(fileRead).useDelimiter("\\Z");
+	    String readContent = scanner.next();
+	    String transformedContent = readContent.replaceAll("^name$", "firstname");
+	    assertEquals("XML document write difference", transformedContent, readContent);
+	    scanner.close();	    
+	    
+	    // release client
+	    client.release();
+	}
+	@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		deleteRESTServerWithDB("REST-Java-Client-API-Server");
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestValueConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestValueConstraint.java
new file mode 100644
index 000000000..b3d7ef816
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestValueConstraint.java
@@ -0,0 +1,215 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.query.QueryManager;
+import com.marklogic.client.admin.QueryOptionsManager;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.query.MatchDocumentSummary;
+import com.marklogic.client.query.MatchLocation;
+import com.marklogic.client.query.StringQueryDefinition;
+import com.marklogic.client.io.ReaderHandle;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestValueConstraint extends BasicJavaClientREST {
+	
+	static final private String[] filenames = {"value-constraint-doc.xml", "value-constraint-doc2.xml"};
+	
+	private static String dbName = "ValueConstraintDB";
+	private static String [] fNames = {"ValueConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0],  restServerName,8011);
+	}
+	
+@SuppressWarnings("deprecation")
+@Test	public void testElementValueConstraint() throws FileNotFoundException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+
+		String docId = null;
+		
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+
+		// write the files
+		for (String filename: filenames) 
+		{	
+			// acquire the content
+			BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/data/" + filename));
+			
+		    // create an identifier for the document
+		    docId = "/value-constraint/" + filename;
+		    
+		    handle.set(docStream);
+		    
+		    // write the document content
+		    docMgr.write(docId, handle);
+		    
+		    System.out.println("Write " + docId + " to database");
+		}
+	    
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create the query options
+		StringBuilder builder = new StringBuilder();
+		builder.append("\n");
+		builder.append("\n");
+		builder.append("  \n");
+		builder.append("    \n");
+		builder.append("      \n");
+		builder.append("    \n");
+		builder.append("  \n");
+		builder.append("  \n");
+		builder.append("    \n");
+		builder.append("      \n");
+		builder.append("      \n");
+		builder.append("    \n");
+		builder.append("  \n");
+		builder.append("\n");
+		
+		// initialize a handle with the query options
+		StringHandle writeHandle = new StringHandle(builder.toString());
+				
+		// write the query options to the database
+		optionsMgr.writeOptions("valueConstraintOpt", writeHandle);
+				
+		// create a manager for searching
+		QueryManager queryMgr = client.newQueryManager();
+
+		// create a search definition
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("valueConstraintOpt");
+		querydef.setCriteria("my-element-value:\"Indiana Jones\"");
+
+		// create a handle for the search results
+		SearchHandle resultsHandle = new SearchHandle();
+
+		// run the search
+		queryMgr.search(querydef, resultsHandle);
+						
+		// iterate over the result documents
+		MatchDocumentSummary[] docSummaries = resultsHandle.getMatchResults();
+		String searchMatch = "";
+		for (MatchDocumentSummary docSummary: docSummaries) {
+			String uri = docSummary.getUri();
+
+			// iterate over the match locations within a result document
+			MatchLocation[] locations = docSummary.getMatchLocations();
+			searchMatch = "Matched " + locations.length + " locations in "+ uri;			
+		}
+		
+		String expectedSearchMatch = "Matched 1 locations in /value-constraint/value-constraint-doc2.xml";
+		assertEquals("Search match difference", expectedSearchMatch, searchMatch);
+		
+		// release client
+		client.release();
+	}
+	
+@SuppressWarnings("deprecation")
+@Test	public void testAttributeValueConstraint() throws FileNotFoundException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// create doc manager
+		XMLDocumentManager docMgr = client.newXMLDocumentManager();
+
+		// create doc id
+		String docId = null;
+
+		// create handle
+		ReaderHandle handle = new ReaderHandle();
+
+		// write the files
+		for (String filename: filenames) 
+		{	
+			// acquire the content
+			BufferedReader docStream = new BufferedReader(new FileReader("src/test/java/com/marklogic/javaclient/data/" + filename));
+			
+		    // create an identifier for the document
+		    docId = "/value-constraint/" + filename;
+		    
+		    handle.set(docStream);
+		    
+		    // write the document content
+		    docMgr.write(docId, handle);
+		    
+		    System.out.println("Write " + docId + " to database");
+		}	    
+		// create a manager for writing query options
+		QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
+
+		// create the query options
+		StringBuilder builder = new StringBuilder();
+		builder.append("\n");
+		builder.append("\n");
+		builder.append("  \n");
+		builder.append("    \n");
+		builder.append("      \n");
+		builder.append("    \n");
+		builder.append("  \n");
+		builder.append("  \n");
+		builder.append("    \n");
+		builder.append("      \n");
+		builder.append("      \n");
+		builder.append("    \n");
+		builder.append("  \n");
+		builder.append("\n");
+		
+		// initialize a handle with the query options
+		StringHandle writeHandle = new StringHandle(builder.toString());
+				
+		// write the query options to the database
+		optionsMgr.writeOptions("valueConstraintOpt", writeHandle);
+				
+		// create a manager for searching
+		QueryManager queryMgr = client.newQueryManager();
+
+		// create a search definition
+		StringQueryDefinition querydef = queryMgr.newStringDefinition("valueConstraintOpt");
+		querydef.setCriteria("my-attribute-value:2005");
+
+		// create a handle for the search results
+		SearchHandle resultsHandle = new SearchHandle();
+
+		// run the search
+		queryMgr.search(querydef, resultsHandle);
+						
+		// iterate over the result documents
+		MatchDocumentSummary[] docSummaries = resultsHandle.getMatchResults();
+		String searchMatch = "";
+		for (MatchDocumentSummary docSummary: docSummaries) {
+			String uri = docSummary.getUri();
+
+			// iterate over the match locations within a result document
+			MatchLocation[] locations = docSummary.getMatchLocations();
+			searchMatch = "Matched " + locations.length + " locations in "+ uri;			
+		}
+		
+		String expectedSearchMatch = "Matched 1 locations in /value-constraint/value-constraint-doc.xml";
+		assertEquals("Search match difference", expectedSearchMatch, searchMatch);
+		
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames,  restServerName);
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestWordConstraint.java b/test-complete/src/test/java/com/marklogic/javaclient/TestWordConstraint.java
new file mode 100644
index 000000000..500703da4
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestWordConstraint.java
@@ -0,0 +1,64 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import com.marklogic.client.io.SearchHandle;
+import com.marklogic.javaclient.BasicJavaClientREST;
+import org.junit.*;
+public class TestWordConstraint extends BasicJavaClientREST {
+	
+	static String filenames[] = {"word-constraint-doc1.xml", "word-constraint-doc2.xml"};
+	static String queryOptionName = "wordConstraintOpt.xml"; 
+	private static String dbName = "WordConstraintDB";
+	private static String [] fNames = {"WordConstraintDB-1"};
+	private static String restServerName = "REST-Java-Client-API-Server";
+	
+@BeforeClass	public static void setUp() throws Exception
+	{
+		System.out.println("In setup");
+		setupJavaRESTServer(dbName, fNames[0],restServerName,8011);
+	}
+	
+@SuppressWarnings("deprecation")
+@Test	public void testElementWordConstraint() throws IOException
+	{
+		DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-admin", "x", Authentication.DIGEST);
+		
+		// write docs
+		for(String filename:filenames)
+		{
+			writeDocumentReaderHandle(client, filename, "/word-constraint/", "XML");
+		}
+
+						
+		// write the query options to the database
+		setQueryOption(client, queryOptionName);
+							
+		// run the search
+		SearchHandle resultsHandle = runSearch(client, queryOptionName, "my-element-word:paris");
+		
+		// search result
+		String searchResult = returnSearchResult(resultsHandle);
+						
+		String expectedSearchResult = "|Matched 1 locations in /word-constraint/word-constraint-doc1.xml";
+		
+		System.out.println(searchResult);
+		
+		assertEquals("Search result difference", expectedSearchResult, searchResult);
+		
+		// release client
+		client.release();
+	}
+	
+@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		tearDownJavaRESTServer(dbName, fNames, restServerName);
+	}
+}
+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestWriteTextDoc.java b/test-complete/src/test/java/com/marklogic/javaclient/TestWriteTextDoc.java
new file mode 100644
index 000000000..5f6fc725d
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestWriteTextDoc.java
@@ -0,0 +1,37 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+
+import com.marklogic.client.document.TextDocumentManager;
+import com.marklogic.client.io.StringHandle;
+import org.junit.*;
+public class TestWriteTextDoc extends BasicJavaClientREST
+{
+
+	@BeforeClass public static void setUp() throws Exception 
+		{
+		  System.out.println("In setup");
+		  setupJavaRESTServerWithDB( "REST-Java-Client-API-Server", 8011);
+		 
+		}
+	
+	@SuppressWarnings("deprecation")
+	@Test  public void testWriteTextDoc()  
+  {
+    DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "admin", "admin", Authentication.DIGEST);
+
+    String docId = "/foo/test/myFoo.txt";
+    TextDocumentManager docMgr = client.newTextDocumentManager();
+    docMgr.write(docId, new StringHandle().with("This is so foo"));
+    assertEquals("Text document write difference", "This is so foo", docMgr.read(docId, new StringHandle()).get());
+  }
+	@AfterClass	public static void tearDown() throws Exception
+	{
+		System.out.println("In tear down");
+		deleteRESTServerWithDB("REST-Java-Client-API-Server");
+	}
+}
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestXMLDocumentRepair.java b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLDocumentRepair.java
new file mode 100644
index 000000000..3dd6f6816
--- /dev/null
+++ b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLDocumentRepair.java
@@ -0,0 +1,96 @@
+package com.marklogic.javaclient;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.Scanner;
+
+import com.marklogic.client.DatabaseClient;
+import com.marklogic.client.DatabaseClientFactory;
+import com.marklogic.client.document.XMLDocumentManager;
+import com.marklogic.client.document.XMLDocumentManager.DocumentRepair;
+import com.marklogic.client.io.FileHandle;
+import com.marklogic.client.DatabaseClientFactory.Authentication;
+import org.junit.*;
+public class TestXMLDocumentRepair extends BasicJavaClientREST {
+	@BeforeClass public static void setUp() throws Exception 
+	{
+	  System.out.println("In setup");
+	  setupJavaRESTServerWithDB( "REST-Java-Client-API-Server", 8011);
+	 
+	}
+	
+	@SuppressWarnings("deprecation")
+	@Test	public void testXMLDocumentRepairFull() throws IOException
+	{
+		// acquire the content 
+		File file = new File("repairXMLFull.xml");
+		file.delete();
+		boolean success = file.createNewFile();
+		if(success)
+			System.out.println("New file created on " + file.getAbsolutePath());
+		else
+			System.out.println("Cannot create file");
+				
+		BufferedWriter out = new BufferedWriter(new FileWriter(file));
+		
+		String xmlContent = 
+				"\n" +
+				"\n" +
+				  "

This is bold and italic within the paragraph.

\n" + + "

This is bold and italic within the paragraph.

\n" + + "

This is bold and italic within the paragraph.

\n" + + "
"; + + String repairedContent = + "\n" + + "\n" + + "

This is bold and italic within the paragraph.

\n" + + "

This is bold and italic within the paragraph.

\n" + + "

This is bold and italic within the paragraph.

\n" + + "
"; + + out.write(xmlContent); + out.close(); + + // create database client + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST); + + // create doc id + String docId = "/repair/xml/" + file.getName(); + + // create document manager + XMLDocumentManager docMgr = client.newXMLDocumentManager(); + + // set document repair + docMgr.setDocumentRepair(DocumentRepair.FULL); + + // create a handle on the content + FileHandle handle = new FileHandle(file); + handle.set(file); + + // write the document content + docMgr.write(docId, handle); + + System.out.println("Write " + docId + " to database"); + + // read the document + docMgr.read(docId, handle); + + // access the document content + File fileRead = handle.get(); + + Scanner scanner = new Scanner(fileRead).useDelimiter("\\Z"); + String readContent = scanner.next(); + assertEquals("XML document write difference", repairedContent, readContent); + scanner.close(); + + // release the client + client.release(); + } + @AfterClass public static void tearDown() throws Exception + { + System.out.println("In tear down"); + deleteRESTServerWithDB("REST-Java-Client-API-Server"); + } +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestXMLEventReaderHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLEventReaderHandle.java new file mode 100644 index 000000000..d5f98cbb7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLEventReaderHandle.java @@ -0,0 +1,124 @@ +package com.marklogic.javaclient; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.TransformerException; + +import org.custommonkey.xmlunit.XMLUnit; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.io.ReaderHandle; +import com.marklogic.client.io.XMLEventReaderHandle; +import com.marklogic.javaclient.BasicJavaClientREST; + +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.*; + +import org.junit.*; +public class TestXMLEventReaderHandle extends BasicJavaClientREST { + + private static String dbName = "XMLEventReaderHandleDB"; + private static String [] fNames = {"XMLEventReaderHandleDB-1"}; + private static String restServerName = "REST-Java-Client-API-Server"; + +@BeforeClass public static void setUp() throws Exception + { + System.out.println("In setup"); + setupJavaRESTServer(dbName, fNames[0], restServerName,8011); + } + +@SuppressWarnings("deprecation") +@Test public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException, TransformerException, XMLStreamException + { + String filename = "xml-original-test.xml"; + String uri = "/write-xml-XMLEventReaderHandle/"; + + System.out.println("Running testXmlCRUD"); + + // connect the client + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST); + + // write the doc + writeDocumentReaderHandle(client, filename, uri, "XML"); + + // read the document + XMLEventReaderHandle readHandle = readDocumentUsingXMLEventReaderHandle(client, uri + filename, "XML"); + + // access the document content + XMLEventReader fileRead = readHandle.get(); + + String readContent = convertXMLEventReaderToString(fileRead); + String readContentCrop = readContent.substring(0, readContent.length()-11); + System.out.println(readContentCrop); + + // get xml document for expected result + Document expectedDoc = expectedXMLDocument(filename); + + String expectedContent = convertXMLDocumentToString(expectedDoc); + System.out.println(expectedContent); + // convert actual string to xml doc + Document readDoc = convertStringToXMLDocument(readContentCrop); + + assertXMLEqual("Write XML difference", expectedDoc,readDoc); + + // update the doc + // acquire the content for update + String updateFilename = "xml-updated-test.xml"; + updateDocumentReaderHandle(client, updateFilename, uri + filename, "XML"); + + // read the document + XMLEventReaderHandle updateHandle = readDocumentUsingXMLEventReaderHandle(client, uri + filename, "XML"); + + // access the document content + XMLEventReader fileReadUpdate = updateHandle.get(); + + String readContentUpdate = convertXMLEventReaderToString(fileReadUpdate); + String readContentUpdateCrop = readContentUpdate.substring(0,readContentUpdate.length()-11); + // get xml document for expected result + Document expectedDocUpdate = expectedXMLDocument(updateFilename); + + // convert actual string to xml doc + Document readDocUpdate = convertStringToXMLDocument(readContentUpdateCrop); + + assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate); + + + // delete the document + deleteDocument(client, uri + filename, "XML"); + + // read the deleted document + //assertFalse("Document is not deleted", isDocumentExist(client, "/write-xml-readerhandle/" + filename, "XML")); + + String exception = ""; + try + { + ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "XML"); + } catch (Exception e) { exception = e.toString(); } + + String expectedException = "Could not read non-existent document"; + boolean documentIsDeleted = exception.contains(expectedException); + assertTrue("Document is not deleted", documentIsDeleted); + + + + // release the client + client.release(); + } + +@AfterClass public static void tearDown() throws Exception + { + System.out.println("In tear down"); + tearDownJavaRESTServer(dbName, fNames, restServerName); + + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestXMLMultiByte.java b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLMultiByte.java new file mode 100644 index 000000000..422a82499 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLMultiByte.java @@ -0,0 +1,104 @@ +package com.marklogic.javaclient; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.io.DOMHandle; +import com.marklogic.client.io.InputStreamHandle; +import com.marklogic.javaclient.BasicJavaClientREST; + +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.*; +public class TestXMLMultiByte extends BasicJavaClientREST { + + private static String dbName = "XMLMultiByteDB"; + private static String [] fNames = {"XMLMultiByteDB-1"}; + private static String restServerName = "REST-Java-Client-API-Server"; + +@BeforeClass public static void setUp() throws Exception + { + System.out.println("In setup"); + setupJavaRESTServer(dbName, fNames[0], restServerName,8011); + } + +@SuppressWarnings("deprecation") +@Test public void testXmlMultibyte() throws IOException, SAXException, ParserConfigurationException, TransformerException + { + String filename = "multibyte-original.xml"; + String uri = "/write-xml-multibyte/"; + + System.out.println("Running testXmlMultibyte"); + + XMLUnit.setIgnoreWhitespace(true); + XMLUnit.setNormalizeWhitespace(true); + + // connect the client + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST); + + // write docs + writeDocumentUsingInputStreamHandle(client, filename, uri, "XML"); + + // read docs + DOMHandle contentHandle = readDocumentUsingDOMHandle(client, uri + filename, "XML"); + + // get the contents + Document readDoc = contentHandle.get(); + + // get xml document for expected result + Document expectedDoc = expectedXMLDocument(filename); + + assertXMLEqual("Write XML difference", expectedDoc, readDoc); + + // update the doc + // acquire the content for update + String updateFilename = "multibyte-updated.xml"; + updateDocumentUsingInputStreamHandle(client, updateFilename, uri + filename, "XML"); + + // read the document + DOMHandle updateHandle = readDocumentUsingDOMHandle(client, uri + filename, "XML"); + + // get the contents + Document readDocUpdate = updateHandle.get(); + + // get xml document for expected result + Document expectedDocUpdate = expectedXMLDocument(updateFilename); + + assertXMLEqual("Write XML difference", expectedDocUpdate, readDocUpdate); + + // delete the document + deleteDocument(client, uri + filename, "XML"); + + // read the deleted document + //assertFalse("Document is not deleted", isDocumentExist(client, uri + filename, "XML")); + + // release client + client.release(); + } + +@AfterClass public static void tearDown() throws Exception + { + System.out.println("In tear down"); + tearDownJavaRESTServer(dbName, fNames,restServerName); + } +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/TestXMLStreamReaderHandle.java b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLStreamReaderHandle.java new file mode 100644 index 000000000..c5219f45c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/TestXMLStreamReaderHandle.java @@ -0,0 +1,94 @@ +package com.marklogic.javaclient; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.TransformerException; + +import org.custommonkey.xmlunit.XMLUnit; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.io.ReaderHandle; +import com.marklogic.client.io.XMLStreamReaderHandle; +import com.marklogic.javaclient.BasicJavaClientREST; + +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.*; + +import org.junit.*; +public class TestXMLStreamReaderHandle extends BasicJavaClientREST { + + + private static String dbName = "XMLStreamReaderHandleDB"; + private static String [] fNames = {"XMLStreamReaderHandleDB-1"}; + private static String restServerName = "REST-Java-Client-API-Server"; + +@BeforeClass public static void setUp() throws Exception + { + System.out.println("In setup"); + setupJavaRESTServer(dbName, fNames[0],restServerName,8011); + } + +@SuppressWarnings("deprecation") +@Test public void testXmlCRUD() throws IOException, SAXException, ParserConfigurationException, TransformerException, XMLStreamException + { + String filename = "xml-original-test.xml"; + String uri = "/write-xml-XMLStreamReaderHandle/"; + + System.out.println("Running testXmlCRUD"); + + // connect the client + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8011, "rest-writer", "x", Authentication.DIGEST); + + // write the doc + writeDocumentReaderHandle(client, filename, uri, "XML"); + + // read the document + XMLStreamReaderHandle readHandle = readDocumentUsingXMLStreamReaderHandle(client, uri + filename, "XML"); + + // access the document content + XMLStreamReader fileRead = readHandle.get(); + String readContent = convertXMLStreamReaderToString(fileRead); + + // get xml document for expected result + Document expectedDoc = expectedXMLDocument(filename); + String expectedContent = convertXMLDocumentToString(expectedDoc); + expectedContent = "null"+expectedContent.substring(expectedContent.indexOf("")+6, expectedContent.indexOf("")); + assertEquals("Write XML difference", expectedContent,readContent); + + // delete the document + deleteDocument(client, uri + filename, "XML"); + + // read the deleted document + //assertFalse("Document is not deleted", isDocumentExist(client, "/write-xml-readerhandle/" + filename, "XML")); + + String exception = ""; + try + { + ReaderHandle deleteHandle = readDocumentReaderHandle(client, uri + filename, "XML"); + } catch (Exception e) { exception = e.toString(); } + + String expectedException = "Could not read non-existent document"; + boolean documentIsDeleted = exception.contains(expectedException); + assertTrue("Document is not deleted", documentIsDeleted); + + // release the client + client.release(); + } + +@AfterClass public static void tearDown() throws Exception + { + System.out.println("In tear down"); + tearDownJavaRESTServer(dbName, fNames,restServerName); + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/ThreadClass.java b/test-complete/src/test/java/com/marklogic/javaclient/ThreadClass.java new file mode 100644 index 000000000..8e48c8bd9 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/ThreadClass.java @@ -0,0 +1,47 @@ +package com.marklogic.javaclient; + +import org.junit.BeforeClass; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.document.TextDocumentManager; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.io.StringHandle; + +public class ThreadClass extends Thread{ + + String msg; + + public void run() + { + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8013, "rest-admin", "x", Authentication.DIGEST); + + TextDocumentManager docMgr = client.newTextDocumentManager(); + + for(int i=1; i<=5; i++) + { + System.out.println("Writing document from: "+ msg); + + if(msg == "Thread A") + { + // write docs + String docId = "/multithread-content-A/filename" + i + ".txt"; + docMgr.write(docId, new StringHandle().with("This is so foo")); + } + else if(msg == "Thread B") + { + // write docs + String docId = "/multithread-content-B/filename" + i + ".txt"; + docMgr.write(docId, new StringHandle().with("This is so foo")); + } + } + + // release client + client.release(); + } + + ThreadClass(String mg) + { + msg=mg; + } +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/ThreadSearch.java b/test-complete/src/test/java/com/marklogic/javaclient/ThreadSearch.java new file mode 100644 index 000000000..940b168af --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/ThreadSearch.java @@ -0,0 +1,62 @@ +package com.marklogic.javaclient; + +import java.util.Random; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.query.QueryManager; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.query.StringQueryDefinition; +import com.marklogic.client.io.SearchHandle; + +public class ThreadSearch extends Thread { + + String msg; + long totalResultsArray[] = new long[10]; + long totalAllResults = 0; + + public void run() + { + long totalResults = 0; + + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8013, "rest-reader", "x", Authentication.DIGEST); + + QueryManager queryMgr = client.newQueryManager(); + StringQueryDefinition querydef = queryMgr.newStringDefinition(null); + + // create handle + SearchHandle resultsHandle = new SearchHandle(); + + for(int i=1; i<=10; i++) + { + System.out.println("Searching document " + i + " from: " + msg); + + // search docs + querydef.setCriteria("alert"); + queryMgr.search(querydef, resultsHandle); + + totalResults = resultsHandle.getTotalResults(); + + System.out.println("Results: " + totalResults + " documents returned"); + + totalResultsArray[i-1] = totalResults; + + totalAllResults = totalAllResults + totalResults; + + Random rand = new Random(); + int r = rand.nextInt(3000) + 1000; + + try { + Thread.sleep(r); + } catch (InterruptedException e) { e.printStackTrace(); } + } + + // release client + client.release(); + } + + ThreadSearch(String mg) + { + msg=mg; + } +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/ThreadWrite.java b/test-complete/src/test/java/com/marklogic/javaclient/ThreadWrite.java new file mode 100644 index 000000000..e63e02768 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/ThreadWrite.java @@ -0,0 +1,50 @@ +package com.marklogic.javaclient; + +import java.io.File; +import java.util.Random; + +import com.marklogic.client.DatabaseClient; +import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.DatabaseClientFactory.Authentication; +import com.marklogic.client.document.XMLDocumentManager; +import com.marklogic.client.io.FileHandle; + +public class ThreadWrite extends Thread{ + + String msg; + + public void run() + { + String filename = "flipper.xml"; + + DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8013, "rest-writer", "x", Authentication.DIGEST); + + File file = new File("src/test/java/com/marklogic/javaclient/data/" + filename); + + XMLDocumentManager docMgr = client.newXMLDocumentManager(); + + for(int i=1; i<=15; i++) + { + System.out.println("Writing document " + i + " from: " + msg); + + // write docs + String docId = "/multithread-write/filename" + i + ".xml"; + docMgr.write(docId, new FileHandle().with(file)); + + Random rand = new Random(); + int r = rand.nextInt(2000) + 1000; + + try { + Thread.sleep(r); + } catch (InterruptedException e) { e.printStackTrace(); } + } + + // release client + client.release(); + } + + ThreadWrite(String mg) + { + msg=mg; + } +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/LexiconOptions.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/LexiconOptions.xml new file mode 100644 index 000000000..052c0391a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/LexiconOptions.xml @@ -0,0 +1,32 @@ + + + + + + + limit=2 + + + + + + + + + + + + + + + + + + + + ascending + + true + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryNoOption.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryNoOption.xml new file mode 100644 index 000000000..e95b1b660 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryNoOption.xml @@ -0,0 +1,8 @@ + + + + id + 0026 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOption.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOption.xml new file mode 100644 index 000000000..70a4e65b8 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOption.xml @@ -0,0 +1,19 @@ + + + + id + 0026 + + + + false + false + true + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollection.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollection.xml new file mode 100644 index 000000000..f480bd459 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollection.xml @@ -0,0 +1,36 @@ + + + + + + coll + set1 + + + coll + set5 + + + + + intitle + memex + + + + + + false + true + false + + + + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollectionOverwrite.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollectionOverwrite.xml new file mode 100644 index 000000000..7eb2c9c5b --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCollectionOverwrite.xml @@ -0,0 +1,22 @@ + + + + id + 0011 + + + + false + true + false + + + + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCombo.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCombo.xml new file mode 100644 index 000000000..97d644107 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionCombo.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + coll + set1 + + + coll + set5 + + + + + intitle + memex + + + + + + pop + high + + + pop + medium + + + + + price + low + + + + id + **11 + + + + date + 2005-01-01 + + + + + para + Bush + + + + para + memex + + + + + + + false + false + true + + + + + + + + + + + + + + + + + + + + + case-insensitive + + + + + + High + Medium + Low + + + + + + + High + Medium + Low + + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionComboJSON.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionComboJSON.json new file mode 100644 index 000000000..dae311caa --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionComboJSON.json @@ -0,0 +1,275 @@ +{ + "search": { + "options": { + "sort-order": [ + { + "element": { + "ns": "", + "name": "title" + } + } + ], + "constraint": [ + { + "name": "id", + "value": { + "element": { + "ns": "", + "name": "id" + } + } + }, + { + "name": "date", + "range": { + "type": "xs:date", + "facet": false, + "element": { + "ns": "http://purl.org/dc/elements/1.1/", + "name": "date" + } + } + }, + { + "name": "coll", + "collection": { + "prefix": "http://test.com/", + "facet": true + } + }, + { + "name": "para", + "word": { + "term-option": [ + "case-insensitive" + ], + "field": { + "name": "para" + } + } + }, + { + "name": "pop", + "range": { + "type": "xs:int", + "facet": true, + "bucket": [ + { + "name": "high", + "ge": "5", + "label": "High" + }, + { + "name": "medium", + "ge": "3", + "lt": "5", + "label": "Medium" + }, + { + "name": "low", + "ge": "1", + "lt": "3", + "label": "Low" + } + ], + "element": { + "ns": "", + "name": "popularity" + } + } + }, + { + "name": "price", + "range": { + "type": "xs:decimal", + "facet": false, + "bucket": [ + { + "name": "high", + "ge": "120", + "label": "High" + }, + { + "name": "medium", + "ge": "3", + "lt": "14", + "label": "Medium" + }, + { + "name": "low", + "ge": "0", + "lt": "2", + "label": "Low" + } + ], + "element": { + "ns": "http://cloudbank.com", + "name": "price" + }, + "attribute": { + "ns": "", + "name": "amt" + } + } + }, + { + "name": "intitle", + "word": { + "element": { + "ns": "", + "name": "title" + } + } + } + ], + "return-metrics": false, + "return-qtext": false, + "debug": true, + "transform-results": { + "apply": "raw" + } + }, + "query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "collection-constraint-query": { + "uri": [ + "set1" + ], + "constraint-name": "coll" + } + }, + { + "collection-constraint-query": { + "uri": [ + "set5" + ], + "constraint-name": "coll" + } + } + ] + } + }, + { + "not-query": { + "word-constraint-query": { + "text": [ + "memex" + ], + "constraint-name": "intitle" + } + } + } + ] + } + }, + { + "or-query": { + "queries": [ + { + "range-constraint-query": { + "value": [ + "high" + ], + "constraint-name": "pop" + } + }, + { + "range-constraint-query": { + "value": [ + "medium" + ], + "constraint-name": "pop" + } + } + ] + } + } + ] + } + }, + { + "range-constraint-query": { + "value": [ + "low" + ], + "constraint-name": "price" + } + } + ] + } + }, + { + "value-constraint-query": { + "text": [ + "**11" + ], + "constraint-name": "id" + } + } + ] + } + }, + { + "range-constraint-query": { + "value": [ + "2005-01-01" + ], + "constraint-name": "date" + } + } + ] + } + }, + { + "and-query": { + "queries": [ + { + "word-constraint-query": { + "text": [ + "Bush" + ], + "constraint-name": "para" + } + }, + { + "not-query": { + "word-constraint-query": { + "text": [ + "memex" + ], + "constraint-name": "para" + } + } + } + ] + } + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionField.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionField.xml new file mode 100644 index 000000000..7f58c20d1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionField.xml @@ -0,0 +1,44 @@ + + + + + + para + Bush + + + + para + memex + + + + + + id + 0026 + + + memex + + + + + + false + true + false + + + + + case-insensitive + + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionFieldJSON.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionFieldJSON.json new file mode 100644 index 000000000..fa11d2027 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionFieldJSON.json @@ -0,0 +1 @@ +{"search":{"options":{"constraint":[{"name":"para", "word":{"term-option":["case-insensitive"], "field":{"name":"para"}}},{"name":"id", "value":{"element":{"ns":"", "name":"id"}}}], "return-metrics":false, "debug":true, "return-qtext":false, "transform-results":{"apply":"snippet"}}, "query":{"queries":[{"or-query":{"queries":[{"and-query":{"queries":[{"word-constraint-query":{"text":["Bush"], "constraint-name":"para"}},{"not-query":{"word-constraint-query":{"text":["memex"], "constraint-name":"para"}}}]}},{"and-query":{"queries":[{"value-constraint-query":{"text":["0026"], "constraint-name":"id"}},{"term-query":{"text":["memex"]}}]}}]}}]}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeo.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeo.xml new file mode 100644 index 000000000..99386acec --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeo.xml @@ -0,0 +1,83 @@ + + + + geo-attr-pair + + 12 + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + tall (21+) + short (0-21) + + + + + + + + + + + + + + + + + + + 25 + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBox.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBox.xml new file mode 100644 index 000000000..09e706147 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBox.xml @@ -0,0 +1,85 @@ + + + + geo-elem-child + + 11 + -5 + 12 + -4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + tall (21+) + short (0-21) + + + + + + + + + + + + + + + + + + + 25 + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWord.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWord.xml new file mode 100644 index 000000000..c44f3ae1a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWord.xml @@ -0,0 +1,90 @@ + + + + + geo-elem-pair + + -12 + 4 + -11 + 5 + + + + karl_kara + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + tall (21+) + short (0-21) + + + + + + + + + + + + + + + + + + + 25 + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWordJSON.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWordJSON.json new file mode 100644 index 000000000..4f92ae257 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoBoxAndWordJSON.json @@ -0,0 +1,184 @@ +{ + "search": { + "options": { + "constraint": [ + { + "name": "geo-elem", + "geo-elem": { + "element": { + "ns": "", + "name": "g-elem-point" + } + } + }, + { + "name": "geo-elem-child", + "geo-elem": { + "parent": { + "ns": "", + "name": "g-elem-child-parent" + }, + "element": { + "ns": "", + "name": "g-elem-child-point" + } + } + }, + { + "name": "geo-elem-pair", + "geo-elem-pair": { + "parent": { + "ns": "", + "name": "g-elem-pair" + }, + "lat": { + "ns": "", + "name": "lat" + }, + "lon": { + "ns": "", + "name": "long" + } + } + }, + { + "name": "geo-attr-pair", + "geo-attr-pair": { + "parent": { + "ns": "", + "name": "g-attr-pair" + }, + "lat": { + "ns": "", + "name": "lat" + }, + "lon": { + "ns": "", + "name": "long" + } + } + }, + { + "name": "eq-name", + "element-query": { + "ns": "", + "name": "name" + } + }, + { + "name": "eq-desc", + "element-query": { + "ns": "", + "name": "description" + } + }, + { + "name": "eq-person", + "element-query": { + "ns": "", + "name": "person" + } + }, + { + "name": "color", + "value": { + "element": { + "ns": "", + "name": "color" + } + } + }, + { + "name": "height", + "range": { + "type": "xs:int", + "element": { + "ns": "", + "name": "height1" + } + } + }, + { + "name": "bucket_height", + "range": { + "type": "xs:int", + "bucket": [ + { + "name": "tall", + "ge": "21", + "label": "tall (21+)" + }, + { + "name": "short", + "lt": "21", + "label": "short (0-21)" + } + ], + "element": { + "ns": "", + "name": "height1" + } + } + }, + { + "name": "word_const", + "word": { + "element": { + "ns": "", + "name": "text" + } + } + }, + { + "name": "field_const", + "word": { + "field": { + "name": "description" + } + } + }, + { + "name": "coll", + "collection": { + "prefix": "http://coll/" + } + }, + { + "name": "prop", + "properties": null + } + ], + "return-metrics": false, + "page-length": 25, + "debug": true + }, + "query": { + "queries": [ + { + "and-query": { + "queries": [ + { + "geospatial-constraint-query": { + "constraint-name": "geo-elem-pair", + "box": { + "south": -12, + "west": 4, + "north": -11, + "east": 5 + } + } + }, + { + "term-query": { + "text": [ + "karl_kara" + ] + } + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoCircle.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoCircle.xml new file mode 100644 index 000000000..4c33f307c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoCircle.xml @@ -0,0 +1,86 @@ + + + + geo-elem-child + + 70 + + 12 + -5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + tall (21+) + short (0-21) + + + + + + + + + + + + + + + + + + + 25 + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoJSON.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoJSON.json new file mode 100644 index 000000000..8d4dd11e7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoJSON.json @@ -0,0 +1,171 @@ +{ + "search": { + "options": { + "constraint": [ + { + "name": "geo-elem", + "geo-elem": { + "element": { + "ns": "", + "name": "g-elem-point" + } + } + }, + { + "name": "geo-elem-child", + "geo-elem": { + "parent": { + "ns": "", + "name": "g-elem-child-parent" + }, + "element": { + "ns": "", + "name": "g-elem-child-point" + } + } + }, + { + "name": "geo-elem-pair", + "geo-elem-pair": { + "parent": { + "ns": "", + "name": "g-elem-pair" + }, + "lat": { + "ns": "", + "name": "lat" + }, + "lon": { + "ns": "", + "name": "long" + } + } + }, + { + "name": "geo-attr-pair", + "geo-attr-pair": { + "parent": { + "ns": "", + "name": "g-attr-pair" + }, + "lat": { + "ns": "", + "name": "lat" + }, + "lon": { + "ns": "", + "name": "long" + } + } + }, + { + "name": "eq-name", + "element-query": { + "ns": "", + "name": "name" + } + }, + { + "name": "eq-desc", + "element-query": { + "ns": "", + "name": "description" + } + }, + { + "name": "eq-person", + "element-query": { + "ns": "", + "name": "person" + } + }, + { + "name": "color", + "value": { + "element": { + "ns": "", + "name": "color" + } + } + }, + { + "name": "height", + "range": { + "type": "xs:int", + "element": { + "ns": "", + "name": "height1" + } + } + }, + { + "name": "bucket_height", + "range": { + "type": "xs:int", + "bucket": [ + { + "name": "tall", + "ge": "21", + "label": "tall (21+)" + }, + { + "name": "short", + "lt": "21", + "label": "short (0-21)" + } + ], + "element": { + "ns": "", + "name": "height1" + } + } + }, + { + "name": "word_const", + "word": { + "element": { + "ns": "", + "name": "text" + } + } + }, + { + "name": "field_const", + "word": { + "field": { + "name": "description" + } + } + }, + { + "name": "coll", + "collection": { + "prefix": "http://coll/" + } + }, + { + "name": "prop", + "properties": null + } + ], + "return-metrics": false, + "page-length": 25, + "debug": true + }, + "query": { + "queries": [ + { + "geospatial-constraint-query": { + "point": [ + { + "latitude": 12, + "longitude": 5 + } + ], + "constraint-name": "geo-attr-pair" + } + } + ] + } + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoPointAndWord.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoPointAndWord.xml new file mode 100644 index 000000000..7a91de232 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionGeoPointAndWord.xml @@ -0,0 +1,88 @@ + + + + + geo-elem + + 150 + -140 + + + + john + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + tall (21+) + short (0-21) + + + + + + + + + + + + + + + + + + + 25 + true + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSON.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSON.json new file mode 100644 index 000000000..6afb588e7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSON.json @@ -0,0 +1 @@ +{"search":{"query":{"value-constraint-query":{"constraint-name":"id", "text":"0026"}}, "options":{"return-metrics":false, "return-qtext":false, "debug":true, "transform-results":{"apply":"raw"}, "constraint":{"name":"id", "value":{"element":{"ns":"", "name":"id"}}}}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSONOverwrite.json b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSONOverwrite.json new file mode 100644 index 000000000..0f18de146 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionJSONOverwrite.json @@ -0,0 +1 @@ +{"search":{"query":{"value-constraint-query":{"constraint-name":"id", "text":"0011"}}, "options":{"return-metrics":false, "return-qtext":false, "debug":true, "transform-results":{"apply":"raw"}, "constraint":{"name":"title", "value":{"element":{"ns":"", "name":"title"}}}}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionPathIndex.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionPathIndex.xml new file mode 100644 index 000000000..ef4825c09 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionPathIndex.xml @@ -0,0 +1,15 @@ + + + + pindex + Aries + + + + + + /Employee/fn + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionWildcard.xml b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionWildcard.xml new file mode 100644 index 000000000..894258734 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/combined/combinedQueryOptionWildcard.xml @@ -0,0 +1,27 @@ + + + + + id + 00*2 + + + id + 0??6 + + + + + false + false + filtered + true + + + + + wildcarded + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/JenoptikLogo.jpg b/test-complete/src/test/java/com/marklogic/javaclient/data/JenoptikLogo.jpg new file mode 100644 index 000000000..057950766 Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/JenoptikLogo.jpg differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/Jenoptik_Logo.jpg b/test-complete/src/test/java/com/marklogic/javaclient/data/Jenoptik_Logo.jpg new file mode 100644 index 000000000..057950766 Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/Jenoptik_Logo.jpg differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/Pandakarlino.jpg b/test-complete/src/test/java/com/marklogic/javaclient/data/Pandakarlino.jpg new file mode 100644 index 000000000..05deacae6 Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/Pandakarlino.jpg differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/Sega-4MB.jpg b/test-complete/src/test/java/com/marklogic/javaclient/data/Sega-4MB.jpg new file mode 100644 index 000000000..305b7de5d Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/Sega-4MB.jpg differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/Simple_ScanTe.png b/test-complete/src/test/java/com/marklogic/javaclient/data/Simple_ScanTe.png new file mode 100644 index 000000000..d79e2c337 Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/Simple_ScanTe.png differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.json b/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.json new file mode 100644 index 000000000..07e12fb9a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.json @@ -0,0 +1 @@ +{"root""title":"Vannevar Bush", "popularity":"5", "id":"0011", "date":"2005-01-01", "price":{"amt":"0.1"}, "p":"Vannevar Bush wrote an article for The Atlantic Monthly"}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.xml new file mode 100644 index 000000000..75e4b6cc6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/WrongFormat.xml @@ -0,0 +1,7 @@ + + Vannevar Bush + 5 + 0011 + 2005-01-01 + +

Vannevar Bush wrote an article for The Atlantic Monthly

diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/aggr1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr1.xml new file mode 100644 index 000000000..2a21832f1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr1.xml @@ -0,0 +1,10 @@ + + Vannevar Bush + 5 + 0011 + 2005-01-01 + + 56.7 + 3 +

Vannevar Bush wrote an article for The Atlantic Monthly

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/aggr2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr2.xml new file mode 100644 index 000000000..7abdc4905 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr2.xml @@ -0,0 +1,10 @@ + + The Bush article + 4 + 0012 + 2006-02-02 + + 92.45 + 5 +

The Bush article described a device called a Memex.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/aggr3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr3.xml new file mode 100644 index 000000000..24f260f74 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr3.xml @@ -0,0 +1,10 @@ + + For 1945 + 3 + 0113 + 2007-03-03 + + 33.56 + 1 +

For 1945, the thoughts expressed in The Atlantic Monthly were groundbreaking.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/aggr4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr4.xml new file mode 100644 index 000000000..3068844a6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr4.xml @@ -0,0 +1,10 @@ + + Vannevar served + 5 + 0024 + 2008-04-04 + + 12.34 + 3 +

Vannevar served as a prominent policymaker and public intellectual.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/aggr5.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr5.xml new file mode 100644 index 000000000..094976792 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/aggr5.xml @@ -0,0 +1,10 @@ + + The memex + 5 + 0026 + 2009-05-05 + + 77.678 + 2 +

The Memex, unfortunately, had no automated search feature.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/all_well.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/all_well.xml new file mode 100644 index 000000000..adeee9345 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/all_well.xml @@ -0,0 +1,7020 @@ + +All's Well That Ends Well + + +

ASCII text placed in the public domain by Moby Lexical Tools, 1992.

+

SGML markup by Jon Bosak, 1992-1994.

+

XML version by Jon Bosak, 1996-1999.

+

The XML markup in this version is Copyright © 1999 Jon Bosak. +This work may freely be distributed on condition that it not be +modified or altered in any way.

+
+ + +Dramatis Personae + +KING OF FRANCE +DUKE OF FLORENCE +BERTRAM, Count of Rousillon. +LAFEU, an old lord. +PAROLLES, a follower of Bertram. + + +Steward +Clown +servants to the Countess of Rousillon. + + +A Page. +COUNTESS OF ROUSILLON, mother to Bertram. +HELENA, a gentlewoman protected by the Countess. +An old Widow of Florence. +DIANA, daughter to the Widow. + + +VIOLENTA +MARIANA +neighbours and friends to the Widow. + + +Lords, Officers, Soldiers, &c., French and Florentine. + + +SCENE Rousillon; Paris; Florence; Marseilles. + +ALL'S WELL THAT ENDS WELL + +ACT I + +SCENE I. Rousillon. The COUNT's palace. +Enter BERTRAM, the COUNTESS of Rousillon, HELENA, +and LAFEU, all in black + + +COUNTESS +In delivering my son from me, I bury a second husband. + + + +BERTRAM +And I in going, madam, weep o'er my father's death +anew: but I must attend his majesty's command, to +whom I am now in ward, evermore in subjection. + + + +LAFEU +You shall find of the king a husband, madam; you, +sir, a father: he that so generally is at all times +good must of necessity hold his virtue to you; whose +worthiness would stir it up where it wanted rather +than lack it where there is such abundance. + + + +COUNTESS +What hope is there of his majesty's amendment? + + + +LAFEU +He hath abandoned his physicians, madam; under whose +practises he hath persecuted time with hope, and +finds no other advantage in the process but only the +losing of hope by time. + + + +COUNTESS +This young gentlewoman had a father,--O, that +'had'! how sad a passage 'tis!--whose skill was +almost as great as his honesty; had it stretched so +far, would have made nature immortal, and death +should have play for lack of work. Would, for the +king's sake, he were living! I think it would be +the death of the king's disease. + + + +LAFEU +How called you the man you speak of, madam? + + + +COUNTESS +He was famous, sir, in his profession, and it was +his great right to be so: Gerard de Narbon. + + + +LAFEU +He was excellent indeed, madam: the king very +lately spoke of him admiringly and mourningly: he +was skilful enough to have lived still, if knowledge +could be set up against mortality. + + + +BERTRAM +What is it, my good lord, the king languishes of? + + + +LAFEU +A fistula, my lord. + + + +BERTRAM +I heard not of it before. + + + +LAFEU +I would it were not notorious. Was this gentlewoman +the daughter of Gerard de Narbon? + + + +COUNTESS +His sole child, my lord, and bequeathed to my +overlooking. I have those hopes of her good that +her education promises; her dispositions she +inherits, which makes fair gifts fairer; for where +an unclean mind carries virtuous qualities, there +commendations go with pity; they are virtues and +traitors too; in her they are the better for their +simpleness; she derives her honesty and achieves her goodness. + + + +LAFEU +Your commendations, madam, get from her tears. + + + +COUNTESS +'Tis the best brine a maiden can season her praise +in. The remembrance of her father never approaches +her heart but the tyranny of her sorrows takes all +livelihood from her cheek. No more of this, Helena; +go to, no more; lest it be rather thought you affect +a sorrow than have it. + + + +HELENA +I do affect a sorrow indeed, but I have it too. + + + +LAFEU +Moderate lamentation is the right of the dead, +excessive grief the enemy to the living. + + + +COUNTESS +If the living be enemy to the grief, the excess +makes it soon mortal. + + + +BERTRAM +Madam, I desire your holy wishes. + + + +LAFEU +How understand we that? + + + +COUNTESS +Be thou blest, Bertram, and succeed thy father +In manners, as in shape! thy blood and virtue +Contend for empire in thee, and thy goodness +Share with thy birthright! Love all, trust a few, +Do wrong to none: be able for thine enemy +Rather in power than use, and keep thy friend +Under thy own life's key: be cheque'd for silence, +But never tax'd for speech. What heaven more will, +That thee may furnish and my prayers pluck down, +Fall on thy head! Farewell, my lord; +'Tis an unseason'd courtier; good my lord, +Advise him. + + + +LAFEU +He cannot want the best +That shall attend his love. + + + +COUNTESS +Heaven bless him! Farewell, Bertram. + + +Exit + + +BERTRAM +To HELENA The best wishes that can be forged in +your thoughts be servants to you! Be comfortable +to my mother, your mistress, and make much of her. + + + +LAFEU +Farewell, pretty lady: you must hold the credit of +your father. + + +Exeunt BERTRAM and LAFEU + + +HELENA +O, were that all! I think not on my father; +And these great tears grace his remembrance more +Than those I shed for him. What was he like? +I have forgot him: my imagination +Carries no favour in't but Bertram's. +I am undone: there is no living, none, +If Bertram be away. 'Twere all one +That I should love a bright particular star +And think to wed it, he is so above me: +In his bright radiance and collateral light +Must I be comforted, not in his sphere. +The ambition in my love thus plagues itself: +The hind that would be mated by the lion +Must die for love. 'Twas pretty, though plague, +To see him every hour; to sit and draw +His arched brows, his hawking eye, his curls, +In our heart's table; heart too capable +Of every line and trick of his sweet favour: +But now he's gone, and my idolatrous fancy +Must sanctify his reliques. Who comes here? +Enter PAROLLES +Aside +One that goes with him: I love him for his sake; +And yet I know him a notorious liar, +Think him a great way fool, solely a coward; +Yet these fixed evils sit so fit in him, +That they take place, when virtue's steely bones +Look bleak i' the cold wind: withal, full oft we see +Cold wisdom waiting on superfluous folly. + + + +PAROLLES +Save you, fair queen! + + + +HELENA +And you, monarch! + + + +PAROLLES +No. + + + +HELENA +And no. + + + +PAROLLES +Are you meditating on virginity? + + + +HELENA +Ay. You have some stain of soldier in you: let me +ask you a question. Man is enemy to virginity; how +may we barricado it against him? + + + +PAROLLES +Keep him out. + + + +HELENA +But he assails; and our virginity, though valiant, +in the defence yet is weak: unfold to us some +warlike resistance. + + + +PAROLLES +There is none: man, sitting down before you, will +undermine you and blow you up. + + + +HELENA +Bless our poor virginity from underminers and +blowers up! Is there no military policy, how +virgins might blow up men? + + + +PAROLLES +Virginity being blown down, man will quicklier be +blown up: marry, in blowing him down again, with +the breach yourselves made, you lose your city. It +is not politic in the commonwealth of nature to +preserve virginity. Loss of virginity is rational +increase and there was never virgin got till +virginity was first lost. That you were made of is +metal to make virgins. Virginity by being once lost +may be ten times found; by being ever kept, it is +ever lost: 'tis too cold a companion; away with 't! + + + +HELENA +I will stand for 't a little, though therefore I die a virgin. + + + +PAROLLES +There's little can be said in 't; 'tis against the +rule of nature. To speak on the part of virginity, +is to accuse your mothers; which is most infallible +disobedience. He that hangs himself is a virgin: +virginity murders itself and should be buried in +highways out of all sanctified limit, as a desperate +offendress against nature. Virginity breeds mites, +much like a cheese; consumes itself to the very +paring, and so dies with feeding his own stomach. +Besides, virginity is peevish, proud, idle, made of +self-love, which is the most inhibited sin in the +canon. Keep it not; you cannot choose but loose +by't: out with 't! within ten year it will make +itself ten, which is a goodly increase; and the +principal itself not much the worse: away with 't! + + + +HELENA +How might one do, sir, to lose it to her own liking? + + + +PAROLLES +Let me see: marry, ill, to like him that ne'er it +likes. 'Tis a commodity will lose the gloss with +lying; the longer kept, the less worth: off with 't +while 'tis vendible; answer the time of request. +Virginity, like an old courtier, wears her cap out +of fashion: richly suited, but unsuitable: just +like the brooch and the tooth-pick, which wear not +now. Your date is better in your pie and your +porridge than in your cheek; and your virginity, +your old virginity, is like one of our French +withered pears, it looks ill, it eats drily; marry, +'tis a withered pear; it was formerly better; +marry, yet 'tis a withered pear: will you anything with it? + + + +HELENA +Not my virginity yet +There shall your master have a thousand loves, +A mother and a mistress and a friend, +A phoenix, captain and an enemy, +A guide, a goddess, and a sovereign, +A counsellor, a traitress, and a dear; +His humble ambition, proud humility, +His jarring concord, and his discord dulcet, +His faith, his sweet disaster; with a world +Of pretty, fond, adoptious christendoms, +That blinking Cupid gossips. Now shall he-- +I know not what he shall. God send him well! +The court's a learning place, and he is one-- + + + +PAROLLES +What one, i' faith? + + + +HELENA +That I wish well. 'Tis pity-- + + + +PAROLLES +What's pity? + + + +HELENA +That wishing well had not a body in't, +Which might be felt; that we, the poorer born, +Whose baser stars do shut us up in wishes, +Might with effects of them follow our friends, +And show what we alone must think, which never +Return us thanks. + + +Enter Page + + +Page +Monsieur Parolles, my lord calls for you. + + +Exit + + +PAROLLES +Little Helen, farewell; if I can remember thee, I +will think of thee at court. + + + +HELENA +Monsieur Parolles, you were born under a charitable star. + + + +PAROLLES +Under Mars, I. + + + +HELENA +I especially think, under Mars. + + + +PAROLLES +Why under Mars? + + + +HELENA +The wars have so kept you under that you must needs +be born under Mars. + + + +PAROLLES +When he was predominant. + + + +HELENA +When he was retrograde, I think, rather. + + + +PAROLLES +Why think you so? + + + +HELENA +You go so much backward when you fight. + + + +PAROLLES +That's for advantage. + + + +HELENA +So is running away, when fear proposes the safety; +but the composition that your valour and fear makes +in you is a virtue of a good wing, and I like the wear well. + + + +PAROLLES +I am so full of businesses, I cannot answer thee +acutely. I will return perfect courtier; in the +which, my instruction shall serve to naturalize +thee, so thou wilt be capable of a courtier's +counsel and understand what advice shall thrust upon +thee; else thou diest in thine unthankfulness, and +thine ignorance makes thee away: farewell. When +thou hast leisure, say thy prayers; when thou hast +none, remember thy friends; get thee a good husband, +and use him as he uses thee; so, farewell. + + +Exit + + +HELENA +Our remedies oft in ourselves do lie, +Which we ascribe to heaven: the fated sky +Gives us free scope, only doth backward pull +Our slow designs when we ourselves are dull. +What power is it which mounts my love so high, +That makes me see, and cannot feed mine eye? +The mightiest space in fortune nature brings +To join like likes and kiss like native things. +Impossible be strange attempts to those +That weigh their pains in sense and do suppose +What hath been cannot be: who ever strove +So show her merit, that did miss her love? +The king's disease--my project may deceive me, +But my intents are fix'd and will not leave me. + + +Exit + + +SCENE II. Paris. The KING's palace. +Flourish of cornets. Enter the KING of France, +with letters, and divers Attendants + + +KING +The Florentines and Senoys are by the ears; +Have fought with equal fortune and continue +A braving war. + + + +First Lord +So 'tis reported, sir. + + + +KING +Nay, 'tis most credible; we here received it +A certainty, vouch'd from our cousin Austria, +With caution that the Florentine will move us +For speedy aid; wherein our dearest friend +Prejudicates the business and would seem +To have us make denial. + + + +First Lord +His love and wisdom, +Approved so to your majesty, may plead +For amplest credence. + + + +KING +He hath arm'd our answer, +And Florence is denied before he comes: +Yet, for our gentlemen that mean to see +The Tuscan service, freely have they leave +To stand on either part. + + + +Second Lord +It well may serve +A nursery to our gentry, who are sick +For breathing and exploit. + + + +KING +What's he comes here? + + +Enter BERTRAM, LAFEU, and PAROLLES + + +First Lord +It is the Count Rousillon, my good lord, +Young Bertram. + + + +KING +Youth, thou bear'st thy father's face; +Frank nature, rather curious than in haste, +Hath well composed thee. Thy father's moral parts +Mayst thou inherit too! Welcome to Paris. + + + +BERTRAM +My thanks and duty are your majesty's. + + + +KING +I would I had that corporal soundness now, +As when thy father and myself in friendship +First tried our soldiership! He did look far +Into the service of the time and was +Discipled of the bravest: he lasted long; +But on us both did haggish age steal on +And wore us out of act. It much repairs me +To talk of your good father. In his youth +He had the wit which I can well observe +To-day in our young lords; but they may jest +Till their own scorn return to them unnoted +Ere they can hide their levity in honour; +So like a courtier, contempt nor bitterness +Were in his pride or sharpness; if they were, +His equal had awaked them, and his honour, +Clock to itself, knew the true minute when +Exception bid him speak, and at this time +His tongue obey'd his hand: who were below him +He used as creatures of another place +And bow'd his eminent top to their low ranks, +Making them proud of his humility, +In their poor praise he humbled. Such a man +Might be a copy to these younger times; +Which, follow'd well, would demonstrate them now +But goers backward. + + + +BERTRAM +His good remembrance, sir, +Lies richer in your thoughts than on his tomb; +So in approof lives not his epitaph +As in your royal speech. + + + +KING +Would I were with him! He would always say-- +Methinks I hear him now; his plausive words +He scatter'd not in ears, but grafted them, +To grow there and to bear,--'Let me not live,'-- +This his good melancholy oft began, +On the catastrophe and heel of pastime, +When it was out,--'Let me not live,' quoth he, +'After my flame lacks oil, to be the snuff +Of younger spirits, whose apprehensive senses +All but new things disdain; whose judgments are +Mere fathers of their garments; whose constancies +Expire before their fashions.' This he wish'd; +I after him do after him wish too, +Since I nor wax nor honey can bring home, +I quickly were dissolved from my hive, +To give some labourers room. + + + +Second Lord +You are loved, sir: +They that least lend it you shall lack you first. + + + +KING +I fill a place, I know't. How long is't, count, +Since the physician at your father's died? +He was much famed. + + + +BERTRAM +Some six months since, my lord. + + + +KING +If he were living, I would try him yet. +Lend me an arm; the rest have worn me out +With several applications; nature and sickness +Debate it at their leisure. Welcome, count; +My son's no dearer. + + + +BERTRAM +Thank your majesty. + + +Exeunt. Flourish + + +SCENE III. Rousillon. The COUNT's palace. +Enter COUNTESS, Steward, and Clown + + +COUNTESS +I will now hear; what say you of this gentlewoman? + + + +Steward +Madam, the care I have had to even your content, I +wish might be found in the calendar of my past +endeavours; for then we wound our modesty and make +foul the clearness of our deservings, when of +ourselves we publish them. + + + +COUNTESS +What does this knave here? Get you gone, sirrah: +the complaints I have heard of you I do not all +believe: 'tis my slowness that I do not; for I know +you lack not folly to commit them, and have ability +enough to make such knaveries yours. + + + +Clown +'Tis not unknown to you, madam, I am a poor fellow. + + + +COUNTESS +Well, sir. + + + +Clown +No, madam, 'tis not so well that I am poor, though +many of the rich are damned: but, if I may have +your ladyship's good will to go to the world, Isbel +the woman and I will do as we may. + + + +COUNTESS +Wilt thou needs be a beggar? + + + +Clown +I do beg your good will in this case. + + + +COUNTESS +In what case? + + + +Clown +In Isbel's case and mine own. Service is no +heritage: and I think I shall never have the +blessing of God till I have issue o' my body; for +they say barnes are blessings. + + + +COUNTESS +Tell me thy reason why thou wilt marry. + + + +Clown +My poor body, madam, requires it: I am driven on +by the flesh; and he must needs go that the devil drives. + + + +COUNTESS +Is this all your worship's reason? + + + +Clown +Faith, madam, I have other holy reasons such as they +are. + + + +COUNTESS +May the world know them? + + + +Clown +I have been, madam, a wicked creature, as you and +all flesh and blood are; and, indeed, I do marry +that I may repent. + + + +COUNTESS +Thy marriage, sooner than thy wickedness. + + + +Clown +I am out o' friends, madam; and I hope to have +friends for my wife's sake. + + + +COUNTESS +Such friends are thine enemies, knave. + + + +Clown +You're shallow, madam, in great friends; for the +knaves come to do that for me which I am aweary of. +He that ears my land spares my team and gives me +leave to in the crop; if I be his cuckold, he's my +drudge: he that comforts my wife is the cherisher +of my flesh and blood; he that cherishes my flesh +and blood loves my flesh and blood; he that loves my +flesh and blood is my friend: ergo, he that kisses +my wife is my friend. If men could be contented to +be what they are, there were no fear in marriage; +for young Charbon the Puritan and old Poysam the +Papist, howsome'er their hearts are severed in +religion, their heads are both one; they may jowl +horns together, like any deer i' the herd. + + + +COUNTESS +Wilt thou ever be a foul-mouthed and calumnious knave? + + + +Clown +A prophet I, madam; and I speak the truth the next +way: +For I the ballad will repeat, +Which men full true shall find; +Your marriage comes by destiny, +Your cuckoo sings by kind. + + + +COUNTESS +Get you gone, sir; I'll talk with you more anon. + + + +Steward +May it please you, madam, that he bid Helen come to +you: of her I am to speak. + + + +COUNTESS +Sirrah, tell my gentlewoman I would speak with her; +Helen, I mean. + + + +Clown +Was this fair face the cause, quoth she, +Why the Grecians sacked Troy? +Fond done, done fond, +Was this King Priam's joy? +With that she sighed as she stood, +With that she sighed as she stood, +And gave this sentence then; +Among nine bad if one be good, +Among nine bad if one be good, +There's yet one good in ten. + + + +COUNTESS +What, one good in ten? you corrupt the song, sirrah. + + + +Clown +One good woman in ten, madam; which is a purifying +o' the song: would God would serve the world so all +the year! we'ld find no fault with the tithe-woman, +if I were the parson. One in ten, quoth a'! An we +might have a good woman born but one every blazing +star, or at an earthquake, 'twould mend the lottery +well: a man may draw his heart out, ere a' pluck +one. + + + +COUNTESS +You'll be gone, sir knave, and do as I command you. + + + +Clown +That man should be at woman's command, and yet no +hurt done! Though honesty be no puritan, yet it +will do no hurt; it will wear the surplice of +humility over the black gown of a big heart. I am +going, forsooth: the business is for Helen to come hither. + + +Exit + + +COUNTESS +Well, now. + + + +Steward +I know, madam, you love your gentlewoman entirely. + + + +COUNTESS +Faith, I do: her father bequeathed her to me; and +she herself, without other advantage, may lawfully +make title to as much love as she finds: there is +more owing her than is paid; and more shall be paid +her than she'll demand. + + + +Steward +Madam, I was very late more near her than I think +she wished me: alone she was, and did communicate +to herself her own words to her own ears; she +thought, I dare vow for her, they touched not any +stranger sense. Her matter was, she loved your son: +Fortune, she said, was no goddess, that had put +such difference betwixt their two estates; Love no +god, that would not extend his might, only where +qualities were level; Dian no queen of virgins, that +would suffer her poor knight surprised, without +rescue in the first assault or ransom afterward. +This she delivered in the most bitter touch of +sorrow that e'er I heard virgin exclaim in: which I +held my duty speedily to acquaint you withal; +sithence, in the loss that may happen, it concerns +you something to know it. + + + +COUNTESS +You have discharged this honestly; keep it to +yourself: many likelihoods informed me of this +before, which hung so tottering in the balance that +I could neither believe nor misdoubt. Pray you, +leave me: stall this in your bosom; and I thank you +for your honest care: I will speak with you further anon. +Exit Steward +Enter HELENA +Even so it was with me when I was young: +If ever we are nature's, these are ours; this thorn +Doth to our rose of youth rightly belong; +Our blood to us, this to our blood is born; +It is the show and seal of nature's truth, +Where love's strong passion is impress'd in youth: +By our remembrances of days foregone, +Such were our faults, or then we thought them none. +Her eye is sick on't: I observe her now. + + + +HELENA +What is your pleasure, madam? + + + +COUNTESS +You know, Helen, +I am a mother to you. + + + +HELENA +Mine honourable mistress. + + + +COUNTESS +Nay, a mother: +Why not a mother? When I said 'a mother,' +Methought you saw a serpent: what's in 'mother,' +That you start at it? I say, I am your mother; +And put you in the catalogue of those +That were enwombed mine: 'tis often seen +Adoption strives with nature and choice breeds +A native slip to us from foreign seeds: +You ne'er oppress'd me with a mother's groan, +Yet I express to you a mother's care: +God's mercy, maiden! does it curd thy blood +To say I am thy mother? What's the matter, +That this distemper'd messenger of wet, +The many-colour'd Iris, rounds thine eye? +Why? that you are my daughter? + + + +HELENA +That I am not. + + + +COUNTESS +I say, I am your mother. + + + +HELENA +Pardon, madam; +The Count Rousillon cannot be my brother: +I am from humble, he from honour'd name; +No note upon my parents, his all noble: +My master, my dear lord he is; and I +His servant live, and will his vassal die: +He must not be my brother. + + + +COUNTESS +Nor I your mother? + + + +HELENA +You are my mother, madam; would you were,-- +So that my lord your son were not my brother,-- +Indeed my mother! or were you both our mothers, +I care no more for than I do for heaven, +So I were not his sister. Can't no other, +But, I your daughter, he must be my brother? + + + +COUNTESS +Yes, Helen, you might be my daughter-in-law: +God shield you mean it not! daughter and mother +So strive upon your pulse. What, pale again? +My fear hath catch'd your fondness: now I see +The mystery of your loneliness, and find +Your salt tears' head: now to all sense 'tis gross +You love my son; invention is ashamed, +Against the proclamation of thy passion, +To say thou dost not: therefore tell me true; +But tell me then, 'tis so; for, look thy cheeks +Confess it, th' one to th' other; and thine eyes +See it so grossly shown in thy behaviors +That in their kind they speak it: only sin +And hellish obstinacy tie thy tongue, +That truth should be suspected. Speak, is't so? +If it be so, you have wound a goodly clew; +If it be not, forswear't: howe'er, I charge thee, +As heaven shall work in me for thine avail, +Tell me truly. + + + +HELENA +Good madam, pardon me! + + + +COUNTESS +Do you love my son? + + + +HELENA +Your pardon, noble mistress! + + + +COUNTESS +Love you my son? + + + +HELENA +Do not you love him, madam? + + + +COUNTESS +Go not about; my love hath in't a bond, +Whereof the world takes note: come, come, disclose +The state of your affection; for your passions +Have to the full appeach'd. + + + +HELENA +Then, I confess, +Here on my knee, before high heaven and you, +That before you, and next unto high heaven, +I love your son. +My friends were poor, but honest; so's my love: +Be not offended; for it hurts not him +That he is loved of me: I follow him not +By any token of presumptuous suit; +Nor would I have him till I do deserve him; +Yet never know how that desert should be. +I know I love in vain, strive against hope; +Yet in this captious and intenible sieve +I still pour in the waters of my love +And lack not to lose still: thus, Indian-like, +Religious in mine error, I adore +The sun, that looks upon his worshipper, +But knows of him no more. My dearest madam, +Let not your hate encounter with my love +For loving where you do: but if yourself, +Whose aged honour cites a virtuous youth, +Did ever in so true a flame of liking +Wish chastely and love dearly, that your Dian +Was both herself and love: O, then, give pity +To her, whose state is such that cannot choose +But lend and give where she is sure to lose; +That seeks not to find that her search implies, +But riddle-like lives sweetly where she dies! + + + +COUNTESS +Had you not lately an intent,--speak truly,-- +To go to Paris? + + + +HELENA +Madam, I had. + + + +COUNTESS +Wherefore? tell true. + + + +HELENA +I will tell truth; by grace itself I swear. +You know my father left me some prescriptions +Of rare and proved effects, such as his reading +And manifest experience had collected +For general sovereignty; and that he will'd me +In heedfull'st reservation to bestow them, +As notes whose faculties inclusive were +More than they were in note: amongst the rest, +There is a remedy, approved, set down, +To cure the desperate languishings whereof +The king is render'd lost. + + + +COUNTESS +This was your motive +For Paris, was it? speak. + + + +HELENA +My lord your son made me to think of this; +Else Paris and the medicine and the king +Had from the conversation of my thoughts +Haply been absent then. + + + +COUNTESS +But think you, Helen, +If you should tender your supposed aid, +He would receive it? he and his physicians +Are of a mind; he, that they cannot help him, +They, that they cannot help: how shall they credit +A poor unlearned virgin, when the schools, +Embowell'd of their doctrine, have left off +The danger to itself? + + + +HELENA +There's something in't, +More than my father's skill, which was the greatest +Of his profession, that his good receipt +Shall for my legacy be sanctified +By the luckiest stars in heaven: and, would your honour +But give me leave to try success, I'ld venture +The well-lost life of mine on his grace's cure +By such a day and hour. + + + +COUNTESS +Dost thou believe't? + + + +HELENA +Ay, madam, knowingly. + + + +COUNTESS +Why, Helen, thou shalt have my leave and love, +Means and attendants and my loving greetings +To those of mine in court: I'll stay at home +And pray God's blessing into thy attempt: +Be gone to-morrow; and be sure of this, +What I can help thee to thou shalt not miss. + + +Exeunt + + + + +ACT II + +SCENE I. Paris. The KING's palace. +Flourish of cornets. Enter the KING, attended +with divers young Lords taking leave for the +Florentine war; BERTRAM, and PAROLLES + + +KING +Farewell, young lords; these warlike principles +Do not throw from you: and you, my lords, farewell: +Share the advice betwixt you; if both gain, all +The gift doth stretch itself as 'tis received, +And is enough for both. + + + +First Lord +'Tis our hope, sir, +After well enter'd soldiers, to return +And find your grace in health. + + + +KING +No, no, it cannot be; and yet my heart +Will not confess he owes the malady +That doth my life besiege. Farewell, young lords; +Whether I live or die, be you the sons +Of worthy Frenchmen: let higher Italy,-- +Those bated that inherit but the fall +Of the last monarchy,--see that you come +Not to woo honour, but to wed it; when +The bravest questant shrinks, find what you seek, +That fame may cry you loud: I say, farewell. + + + +Second Lord +Health, at your bidding, serve your majesty! + + + +KING +Those girls of Italy, take heed of them: +They say, our French lack language to deny, +If they demand: beware of being captives, +Before you serve. + + + +Both +Our hearts receive your warnings. + + + +KING +Farewell. Come hither to me. + + +Exit, attended + + +First Lord +O, my sweet lord, that you will stay behind us! + + + +PAROLLES +'Tis not his fault, the spark. + + + +Second Lord +O, 'tis brave wars! + + + +PAROLLES +Most admirable: I have seen those wars. + + + +BERTRAM +I am commanded here, and kept a coil with +'Too young' and 'the next year' and ''tis too early.' + + + +PAROLLES +An thy mind stand to't, boy, steal away bravely. + + + +BERTRAM +I shall stay here the forehorse to a smock, +Creaking my shoes on the plain masonry, +Till honour be bought up and no sword worn +But one to dance with! By heaven, I'll steal away. + + + +First Lord +There's honour in the theft. + + + +PAROLLES +Commit it, count. + + + +Second Lord +I am your accessary; and so, farewell. + + + +BERTRAM +I grow to you, and our parting is a tortured body. + + + +First Lord +Farewell, captain. + + + +Second Lord +Sweet Monsieur Parolles! + + + +PAROLLES +Noble heroes, my sword and yours are kin. Good +sparks and lustrous, a word, good metals: you shall +find in the regiment of the Spinii one Captain +Spurio, with his cicatrice, an emblem of war, here +on his sinister cheek; it was this very sword +entrenched it: say to him, I live; and observe his +reports for me. + + + +First Lord +We shall, noble captain. + + +Exeunt Lords + + +PAROLLES +Mars dote on you for his novices! what will ye do? + + + +BERTRAM +Stay: the king. + + +Re-enter KING. BERTRAM and PAROLLES retire + + +PAROLLES +To BERTRAM Use a more spacious ceremony to the +noble lords; you have restrained yourself within the +list of too cold an adieu: be more expressive to +them: for they wear themselves in the cap of the +time, there do muster true gait, eat, speak, and +move under the influence of the most received star; +and though the devil lead the measure, such are to +be followed: after them, and take a more dilated farewell. + + + +BERTRAM +And I will do so. + + + +PAROLLES +Worthy fellows; and like to prove most sinewy sword-men. + + +Exeunt BERTRAM and PAROLLES +Enter LAFEU + + +LAFEU +Kneeling Pardon, my lord, for me and for my tidings. + + + +KING +I'll fee thee to stand up. + + + +LAFEU +Then here's a man stands, that has brought his pardon. +I would you had kneel'd, my lord, to ask me mercy, +And that at my bidding you could so stand up. + + + +KING +I would I had; so I had broke thy pate, +And ask'd thee mercy for't. + + + +LAFEU +Good faith, across: but, my good lord 'tis thus; +Will you be cured of your infirmity? + + + +KING +No. + + + +LAFEU +O, will you eat no grapes, my royal fox? +Yes, but you will my noble grapes, an if +My royal fox could reach them: I have seen a medicine +That's able to breathe life into a stone, +Quicken a rock, and make you dance canary +With spritely fire and motion; whose simple touch, +Is powerful to araise King Pepin, nay, +To give great Charlemain a pen in's hand, +And write to her a love-line. + + + +KING +What 'her' is this? + + + +LAFEU +Why, Doctor She: my lord, there's one arrived, +If you will see her: now, by my faith and honour, +If seriously I may convey my thoughts +In this my light deliverance, I have spoke +With one that, in her sex, her years, profession, +Wisdom and constancy, hath amazed me more +Than I dare blame my weakness: will you see her +For that is her demand, and know her business? +That done, laugh well at me. + + + +KING +Now, good Lafeu, +Bring in the admiration; that we with thee +May spend our wonder too, or take off thine +By wondering how thou took'st it. + + + +LAFEU +Nay, I'll fit you, +And not be all day neither. + + +Exit + + +KING +Thus he his special nothing ever prologues. + + +Re-enter LAFEU, with HELENA + + +LAFEU +Nay, come your ways. + + + +KING +This haste hath wings indeed. + + + +LAFEU +Nay, come your ways: +This is his majesty; say your mind to him: +A traitor you do look like; but such traitors +His majesty seldom fears: I am Cressid's uncle, +That dare leave two together; fare you well. + + +Exit + + +KING +Now, fair one, does your business follow us? + + + +HELENA +Ay, my good lord. +Gerard de Narbon was my father; +In what he did profess, well found. + + + +KING +I knew him. + + + +HELENA +The rather will I spare my praises towards him: +Knowing him is enough. On's bed of death +Many receipts he gave me: chiefly one. +Which, as the dearest issue of his practise, +And of his old experience the oily darling, +He bade me store up, as a triple eye, +Safer than mine own two, more dear; I have so; +And hearing your high majesty is touch'd +With that malignant cause wherein the honour +Of my dear father's gift stands chief in power, +I come to tender it and my appliance +With all bound humbleness. + + + +KING +We thank you, maiden; +But may not be so credulous of cure, +When our most learned doctors leave us and +The congregated college have concluded +That labouring art can never ransom nature +From her inaidible estate; I say we must not +So stain our judgment, or corrupt our hope, +To prostitute our past-cure malady +To empirics, or to dissever so +Our great self and our credit, to esteem +A senseless help when help past sense we deem. + + + +HELENA +My duty then shall pay me for my pains: +I will no more enforce mine office on you. +Humbly entreating from your royal thoughts +A modest one, to bear me back a again. + + + +KING +I cannot give thee less, to be call'd grateful: +Thou thought'st to help me; and such thanks I give +As one near death to those that wish him live: +But what at full I know, thou know'st no part, +I knowing all my peril, thou no art. + + + +HELENA +What I can do can do no hurt to try, +Since you set up your rest 'gainst remedy. +He that of greatest works is finisher +Oft does them by the weakest minister: +So holy writ in babes hath judgment shown, +When judges have been babes; great floods have flown +From simple sources, and great seas have dried +When miracles have by the greatest been denied. +Oft expectation fails and most oft there +Where most it promises, and oft it hits +Where hope is coldest and despair most fits. + + + +KING +I must not hear thee; fare thee well, kind maid; +Thy pains not used must by thyself be paid: +Proffers not took reap thanks for their reward. + + + +HELENA +Inspired merit so by breath is barr'd: +It is not so with Him that all things knows +As 'tis with us that square our guess by shows; +But most it is presumption in us when +The help of heaven we count the act of men. +Dear sir, to my endeavours give consent; +Of heaven, not me, make an experiment. +I am not an impostor that proclaim +Myself against the level of mine aim; +But know I think and think I know most sure +My art is not past power nor you past cure. + + + +KING +Are thou so confident? within what space +Hopest thou my cure? + + + +HELENA +The great'st grace lending grace +Ere twice the horses of the sun shall bring +Their fiery torcher his diurnal ring, +Ere twice in murk and occidental damp +Moist Hesperus hath quench'd his sleepy lamp, +Or four and twenty times the pilot's glass +Hath told the thievish minutes how they pass, +What is infirm from your sound parts shall fly, +Health shall live free and sickness freely die. + + + +KING +Upon thy certainty and confidence +What darest thou venture? + + + +HELENA +Tax of impudence, +A strumpet's boldness, a divulged shame +Traduced by odious ballads: my maiden's name +Sear'd otherwise; nay, worse--if worse--extended +With vilest torture let my life be ended. + + + +KING +Methinks in thee some blessed spirit doth speak +His powerful sound within an organ weak: +And what impossibility would slay +In common sense, sense saves another way. +Thy life is dear; for all that life can rate +Worth name of life in thee hath estimate, +Youth, beauty, wisdom, courage, all +That happiness and prime can happy call: +Thou this to hazard needs must intimate +Skill infinite or monstrous desperate. +Sweet practiser, thy physic I will try, +That ministers thine own death if I die. + + + +HELENA +If I break time, or flinch in property +Of what I spoke, unpitied let me die, +And well deserved: not helping, death's my fee; +But, if I help, what do you promise me? + + + +KING +Make thy demand. + + + +HELENA +But will you make it even? + + + +KING +Ay, by my sceptre and my hopes of heaven. + + + +HELENA +Then shalt thou give me with thy kingly hand +What husband in thy power I will command: +Exempted be from me the arrogance +To choose from forth the royal blood of France, +My low and humble name to propagate +With any branch or image of thy state; +But such a one, thy vassal, whom I know +Is free for me to ask, thee to bestow. + + + +KING +Here is my hand; the premises observed, +Thy will by my performance shall be served: +So make the choice of thy own time, for I, +Thy resolved patient, on thee still rely. +More should I question thee, and more I must, +Though more to know could not be more to trust, +From whence thou camest, how tended on: but rest +Unquestion'd welcome and undoubted blest. +Give me some help here, ho! If thou proceed +As high as word, my deed shall match thy meed. + + +Flourish. Exeunt + + +SCENE II. Rousillon. The COUNT's palace. +Enter COUNTESS and Clown + + +COUNTESS +Come on, sir; I shall now put you to the height of +your breeding. + + + +Clown +I will show myself highly fed and lowly taught: I +know my business is but to the court. + + + +COUNTESS +To the court! why, what place make you special, +when you put off that with such contempt? But to the court! + + + +Clown +Truly, madam, if God have lent a man any manners, he +may easily put it off at court: he that cannot make +a leg, put off's cap, kiss his hand and say nothing, +has neither leg, hands, lip, nor cap; and indeed +such a fellow, to say precisely, were not for the +court; but for me, I have an answer will serve all +men. + + + +COUNTESS +Marry, that's a bountiful answer that fits all +questions. + + + +Clown +It is like a barber's chair that fits all buttocks, +the pin-buttock, the quatch-buttock, the brawn +buttock, or any buttock. + + + +COUNTESS +Will your answer serve fit to all questions? + + + +Clown +As fit as ten groats is for the hand of an attorney, +as your French crown for your taffeta punk, as Tib's +rush for Tom's forefinger, as a pancake for Shrove +Tuesday, a morris for May-day, as the nail to his +hole, the cuckold to his horn, as a scolding queen +to a wrangling knave, as the nun's lip to the +friar's mouth, nay, as the pudding to his skin. + + + +COUNTESS +Have you, I say, an answer of such fitness for all +questions? + + + +Clown +From below your duke to beneath your constable, it +will fit any question. + + + +COUNTESS +It must be an answer of most monstrous size that +must fit all demands. + + + +Clown +But a trifle neither, in good faith, if the learned +should speak truth of it: here it is, and all that +belongs to't. Ask me if I am a courtier: it shall +do you no harm to learn. + + + +COUNTESS +To be young again, if we could: I will be a fool in +question, hoping to be the wiser by your answer. I +pray you, sir, are you a courtier? + + + +Clown +O Lord, sir! There's a simple putting off. More, +more, a hundred of them. + + + +COUNTESS +Sir, I am a poor friend of yours, that loves you. + + + +Clown +O Lord, sir! Thick, thick, spare not me. + + + +COUNTESS +I think, sir, you can eat none of this homely meat. + + + +Clown +O Lord, sir! Nay, put me to't, I warrant you. + + + +COUNTESS +You were lately whipped, sir, as I think. + + + +Clown +O Lord, sir! spare not me. + + + +COUNTESS +Do you cry, 'O Lord, sir!' at your whipping, and +'spare not me?' Indeed your 'O Lord, sir!' is very +sequent to your whipping: you would answer very well +to a whipping, if you were but bound to't. + + + +Clown +I ne'er had worse luck in my life in my 'O Lord, +sir!' I see things may serve long, but not serve ever. + + + +COUNTESS +I play the noble housewife with the time +To entertain't so merrily with a fool. + + + +Clown +O Lord, sir! why, there't serves well again. + + + +COUNTESS +An end, sir; to your business. Give Helen this, +And urge her to a present answer back: +Commend me to my kinsmen and my son: +This is not much. + + + +Clown +Not much commendation to them. + + + +COUNTESS +Not much employment for you: you understand me? + + + +Clown +Most fruitfully: I am there before my legs. + + + +COUNTESS +Haste you again. + + +Exeunt severally + + +SCENE III. Paris. The KING's palace. +Enter BERTRAM, LAFEU, and PAROLLES + + +LAFEU +They say miracles are past; and we have our +philosophical persons, to make modern and familiar, +things supernatural and causeless. Hence is it that +we make trifles of terrors, ensconcing ourselves +into seeming knowledge, when we should submit +ourselves to an unknown fear. + + + +PAROLLES +Why, 'tis the rarest argument of wonder that hath +shot out in our latter times. + + + +BERTRAM +And so 'tis. + + + +LAFEU +To be relinquish'd of the artists,-- + + + +PAROLLES +So I say. + + + +LAFEU +Both of Galen and Paracelsus. + + + +PAROLLES +So I say. + + + +LAFEU +Of all the learned and authentic fellows,-- + + + +PAROLLES +Right; so I say. + + + +LAFEU +That gave him out incurable,-- + + + +PAROLLES +Why, there 'tis; so say I too. + + + +LAFEU +Not to be helped,-- + + + +PAROLLES +Right; as 'twere, a man assured of a-- + + + +LAFEU +Uncertain life, and sure death. + + + +PAROLLES +Just, you say well; so would I have said. + + + +LAFEU +I may truly say, it is a novelty to the world. + + + +PAROLLES +It is, indeed: if you will have it in showing, you +shall read it in--what do you call there? + + + +LAFEU +A showing of a heavenly effect in an earthly actor. + + + +PAROLLES +That's it; I would have said the very same. + + + +LAFEU +Why, your dolphin is not lustier: 'fore me, +I speak in respect-- + + + +PAROLLES +Nay, 'tis strange, 'tis very strange, that is the +brief and the tedious of it; and he's of a most +facinerious spirit that will not acknowledge it to be the-- + + + +LAFEU +Very hand of heaven. + + + +PAROLLES +Ay, so I say. + + + +LAFEU +In a most weak-- +pausing +and debile minister, great power, great +transcendence: which should, indeed, give us a +further use to be made than alone the recovery of +the king, as to be-- +pausing +generally thankful. + + + +PAROLLES +I would have said it; you say well. Here comes the king. + + +Enter KING, HELENA, and Attendants. LAFEU and +PAROLLES retire + + +LAFEU +Lustig, as the Dutchman says: I'll like a maid the +better, whilst I have a tooth in my head: why, he's +able to lead her a coranto. + + + +PAROLLES +Mort du vinaigre! is not this Helen? + + + +LAFEU +'Fore God, I think so. + + + +KING +Go, call before me all the lords in court. +Sit, my preserver, by thy patient's side; +And with this healthful hand, whose banish'd sense +Thou hast repeal'd, a second time receive +The confirmation of my promised gift, +Which but attends thy naming. +Enter three or four Lords +Fair maid, send forth thine eye: this youthful parcel +Of noble bachelors stand at my bestowing, +O'er whom both sovereign power and father's voice +I have to use: thy frank election make; +Thou hast power to choose, and they none to forsake. + + + +HELENA +To each of you one fair and virtuous mistress +Fall, when Love please! marry, to each, but one! + + + +LAFEU +I'ld give bay Curtal and his furniture, +My mouth no more were broken than these boys', +And writ as little beard. + + + +KING +Peruse them well: +Not one of those but had a noble father. + + + +HELENA +Gentlemen, +Heaven hath through me restored the king to health. + + + +All +We understand it, and thank heaven for you. + + + +HELENA +I am a simple maid, and therein wealthiest, +That I protest I simply am a maid. +Please it your majesty, I have done already: +The blushes in my cheeks thus whisper me, +'We blush that thou shouldst choose; but, be refused, +Let the white death sit on thy cheek for ever; +We'll ne'er come there again.' + + + +KING +Make choice; and, see, +Who shuns thy love shuns all his love in me. + + + +HELENA +Now, Dian, from thy altar do I fly, +And to imperial Love, that god most high, +Do my sighs stream. Sir, will you hear my suit? + + + +First Lord +And grant it. + + + +HELENA +Thanks, sir; all the rest is mute. + + + +LAFEU +I had rather be in this choice than throw ames-ace +for my life. + + + +HELENA +The honour, sir, that flames in your fair eyes, +Before I speak, too threateningly replies: +Love make your fortunes twenty times above +Her that so wishes and her humble love! + + + +Second Lord +No better, if you please. + + + +HELENA +My wish receive, +Which great Love grant! and so, I take my leave. + + + +LAFEU +Do all they deny her? An they were sons of mine, +I'd have them whipped; or I would send them to the +Turk, to make eunuchs of. + + + +HELENA +Be not afraid that I your hand should take; +I'll never do you wrong for your own sake: +Blessing upon your vows! and in your bed +Find fairer fortune, if you ever wed! + + + +LAFEU +These boys are boys of ice, they'll none have her: +sure, they are bastards to the English; the French +ne'er got 'em. + + + +HELENA +You are too young, too happy, and too good, +To make yourself a son out of my blood. + + + +Fourth Lord +Fair one, I think not so. + + + +LAFEU +There's one grape yet; I am sure thy father drunk +wine: but if thou be'st not an ass, I am a youth +of fourteen; I have known thee already. + + + +HELENA +To BERTRAM I dare not say I take you; but I give +Me and my service, ever whilst I live, +Into your guiding power. This is the man. + + + +KING +Why, then, young Bertram, take her; she's thy wife. + + + +BERTRAM +My wife, my liege! I shall beseech your highness, +In such a business give me leave to use +The help of mine own eyes. + + + +KING +Know'st thou not, Bertram, +What she has done for me? + + + +BERTRAM +Yes, my good lord; +But never hope to know why I should marry her. + + + +KING +Thou know'st she has raised me from my sickly bed. + + + +BERTRAM +But follows it, my lord, to bring me down +Must answer for your raising? I know her well: +She had her breeding at my father's charge. +A poor physician's daughter my wife! Disdain +Rather corrupt me ever! + + + +KING +'Tis only title thou disdain'st in her, the which +I can build up. Strange is it that our bloods, +Of colour, weight, and heat, pour'd all together, +Would quite confound distinction, yet stand off +In differences so mighty. If she be +All that is virtuous, save what thou dislikest, +A poor physician's daughter, thou dislikest +Of virtue for the name: but do not so: +From lowest place when virtuous things proceed, +The place is dignified by the doer's deed: +Where great additions swell's, and virtue none, +It is a dropsied honour. Good alone +Is good without a name. Vileness is so: +The property by what it is should go, +Not by the title. She is young, wise, fair; +In these to nature she's immediate heir, +And these breed honour: that is honour's scorn, +Which challenges itself as honour's born +And is not like the sire: honours thrive, +When rather from our acts we them derive +Than our foregoers: the mere word's a slave +Debosh'd on every tomb, on every grave +A lying trophy, and as oft is dumb +Where dust and damn'd oblivion is the tomb +Of honour'd bones indeed. What should be said? +If thou canst like this creature as a maid, +I can create the rest: virtue and she +Is her own dower; honour and wealth from me. + + + +BERTRAM +I cannot love her, nor will strive to do't. + + + +KING +Thou wrong'st thyself, if thou shouldst strive to choose. + + + +HELENA +That you are well restored, my lord, I'm glad: +Let the rest go. + + + +KING +My honour's at the stake; which to defeat, +I must produce my power. Here, take her hand, +Proud scornful boy, unworthy this good gift; +That dost in vile misprision shackle up +My love and her desert; that canst not dream, +We, poising us in her defective scale, +Shall weigh thee to the beam; that wilt not know, +It is in us to plant thine honour where +We please to have it grow. Cheque thy contempt: +Obey our will, which travails in thy good: +Believe not thy disdain, but presently +Do thine own fortunes that obedient right +Which both thy duty owes and our power claims; +Or I will throw thee from my care for ever +Into the staggers and the careless lapse +Of youth and ignorance; both my revenge and hate +Loosing upon thee, in the name of justice, +Without all terms of pity. Speak; thine answer. + + + +BERTRAM +Pardon, my gracious lord; for I submit +My fancy to your eyes: when I consider +What great creation and what dole of honour +Flies where you bid it, I find that she, which late +Was in my nobler thoughts most base, is now +The praised of the king; who, so ennobled, +Is as 'twere born so. + + + +KING +Take her by the hand, +And tell her she is thine: to whom I promise +A counterpoise, if not to thy estate +A balance more replete. + + + +BERTRAM +I take her hand. + + + +KING +Good fortune and the favour of the king +Smile upon this contract; whose ceremony +Shall seem expedient on the now-born brief, +And be perform'd to-night: the solemn feast +Shall more attend upon the coming space, +Expecting absent friends. As thou lovest her, +Thy love's to me religious; else, does err. + + +Exeunt all but LAFEU and PAROLLES + + +LAFEU +Advancing Do you hear, monsieur? a word with you. + + + +PAROLLES +Your pleasure, sir? + + + +LAFEU +Your lord and master did well to make his +recantation. + + + +PAROLLES +Recantation! My lord! my master! + + + +LAFEU +Ay; is it not a language I speak? + + + +PAROLLES +A most harsh one, and not to be understood without +bloody succeeding. My master! + + + +LAFEU +Are you companion to the Count Rousillon? + + + +PAROLLES +To any count, to all counts, to what is man. + + + +LAFEU +To what is count's man: count's master is of +another style. + + + +PAROLLES +You are too old, sir; let it satisfy you, you are too old. + + + +LAFEU +I must tell thee, sirrah, I write man; to which +title age cannot bring thee. + + + +PAROLLES +What I dare too well do, I dare not do. + + + +LAFEU +I did think thee, for two ordinaries, to be a pretty +wise fellow; thou didst make tolerable vent of thy +travel; it might pass: yet the scarfs and the +bannerets about thee did manifoldly dissuade me from +believing thee a vessel of too great a burthen. I +have now found thee; when I lose thee again, I care +not: yet art thou good for nothing but taking up; and +that thou't scarce worth. + + + +PAROLLES +Hadst thou not the privilege of antiquity upon thee,-- + + + +LAFEU +Do not plunge thyself too far in anger, lest thou +hasten thy trial; which if--Lord have mercy on thee +for a hen! So, my good window of lattice, fare thee +well: thy casement I need not open, for I look +through thee. Give me thy hand. + + + +PAROLLES +My lord, you give me most egregious indignity. + + + +LAFEU +Ay, with all my heart; and thou art worthy of it. + + + +PAROLLES +I have not, my lord, deserved it. + + + +LAFEU +Yes, good faith, every dram of it; and I will not +bate thee a scruple. + + + +PAROLLES +Well, I shall be wiser. + + + +LAFEU +Even as soon as thou canst, for thou hast to pull at +a smack o' the contrary. If ever thou be'st bound +in thy scarf and beaten, thou shalt find what it is +to be proud of thy bondage. I have a desire to hold +my acquaintance with thee, or rather my knowledge, +that I may say in the default, he is a man I know. + + + +PAROLLES +My lord, you do me most insupportable vexation. + + + +LAFEU +I would it were hell-pains for thy sake, and my poor +doing eternal: for doing I am past: as I will by +thee, in what motion age will give me leave. + + +Exit + + +PAROLLES +Well, thou hast a son shall take this disgrace off +me; scurvy, old, filthy, scurvy lord! Well, I must +be patient; there is no fettering of authority. +I'll beat him, by my life, if I can meet him with +any convenience, an he were double and double a +lord. I'll have no more pity of his age than I +would of--I'll beat him, an if I could but meet him again. + + +Re-enter LAFEU + + +LAFEU +Sirrah, your lord and master's married; there's news +for you: you have a new mistress. + + + +PAROLLES +I most unfeignedly beseech your lordship to make +some reservation of your wrongs: he is my good +lord: whom I serve above is my master. + + + +LAFEU +Who? God? + + + +PAROLLES +Ay, sir. + + + +LAFEU +The devil it is that's thy master. Why dost thou +garter up thy arms o' this fashion? dost make hose of +sleeves? do other servants so? Thou wert best set +thy lower part where thy nose stands. By mine +honour, if I were but two hours younger, I'ld beat +thee: methinks, thou art a general offence, and +every man should beat thee: I think thou wast +created for men to breathe themselves upon thee. + + + +PAROLLES +This is hard and undeserved measure, my lord. + + + +LAFEU +Go to, sir; you were beaten in Italy for picking a +kernel out of a pomegranate; you are a vagabond and +no true traveller: you are more saucy with lords +and honourable personages than the commission of your +birth and virtue gives you heraldry. You are not +worth another word, else I'ld call you knave. I leave you. + + +Exit + + +PAROLLES +Good, very good; it is so then: good, very good; +let it be concealed awhile. + + +Re-enter BERTRAM + + +BERTRAM +Undone, and forfeited to cares for ever! + + + +PAROLLES +What's the matter, sweet-heart? + + + +BERTRAM +Although before the solemn priest I have sworn, +I will not bed her. + + + +PAROLLES +What, what, sweet-heart? + + + +BERTRAM +O my Parolles, they have married me! +I'll to the Tuscan wars, and never bed her. + + + +PAROLLES +France is a dog-hole, and it no more merits +The tread of a man's foot: to the wars! + + + +BERTRAM +There's letters from my mother: what the import is, +I know not yet. + + + +PAROLLES +Ay, that would be known. To the wars, my boy, to the wars! +He wears his honour in a box unseen, +That hugs his kicky-wicky here at home, +Spending his manly marrow in her arms, +Which should sustain the bound and high curvet +Of Mars's fiery steed. To other regions +France is a stable; we that dwell in't jades; +Therefore, to the war! + + + +BERTRAM +It shall be so: I'll send her to my house, +Acquaint my mother with my hate to her, +And wherefore I am fled; write to the king +That which I durst not speak; his present gift +Shall furnish me to those Italian fields, +Where noble fellows strike: war is no strife +To the dark house and the detested wife. + + + +PAROLLES +Will this capriccio hold in thee? art sure? + + + +BERTRAM +Go with me to my chamber, and advise me. +I'll send her straight away: to-morrow +I'll to the wars, she to her single sorrow. + + + +PAROLLES +Why, these balls bound; there's noise in it. 'Tis hard: +A young man married is a man that's marr'd: +Therefore away, and leave her bravely; go: +The king has done you wrong: but, hush, 'tis so. + + +Exeunt + + +SCENE IV. Paris. The KING's palace. +Enter HELENA and Clown + + +HELENA +My mother greets me kindly; is she well? + + + +Clown +She is not well; but yet she has her health: she's +very merry; but yet she is not well: but thanks be +given, she's very well and wants nothing i', the +world; but yet she is not well. + + + +HELENA +If she be very well, what does she ail, that she's +not very well? + + + +Clown +Truly, she's very well indeed, but for two things. + + + +HELENA +What two things? + + + +Clown +One, that she's not in heaven, whither God send her +quickly! the other that she's in earth, from whence +God send her quickly! + + +Enter PAROLLES + + +PAROLLES +Bless you, my fortunate lady! + + + +HELENA +I hope, sir, I have your good will to have mine own +good fortunes. + + + +PAROLLES +You had my prayers to lead them on; and to keep them +on, have them still. O, my knave, how does my old lady? + + + +Clown +So that you had her wrinkles and I her money, +I would she did as you say. + + + +PAROLLES +Why, I say nothing. + + + +Clown +Marry, you are the wiser man; for many a man's +tongue shakes out his master's undoing: to say +nothing, to do nothing, to know nothing, and to have +nothing, is to be a great part of your title; which +is within a very little of nothing. + + + +PAROLLES +Away! thou'rt a knave. + + + +Clown +You should have said, sir, before a knave thou'rt a +knave; that's, before me thou'rt a knave: this had +been truth, sir. + + + +PAROLLES +Go to, thou art a witty fool; I have found thee. + + + +Clown +Did you find me in yourself, sir? or were you +taught to find me? The search, sir, was profitable; +and much fool may you find in you, even to the +world's pleasure and the increase of laughter. + + + +PAROLLES +A good knave, i' faith, and well fed. +Madam, my lord will go away to-night; +A very serious business calls on him. +The great prerogative and rite of love, +Which, as your due, time claims, he does acknowledge; +But puts it off to a compell'd restraint; +Whose want, and whose delay, is strew'd with sweets, +Which they distil now in the curbed time, +To make the coming hour o'erflow with joy +And pleasure drown the brim. + + + +HELENA +What's his will else? + + + +PAROLLES +That you will take your instant leave o' the king +And make this haste as your own good proceeding, +Strengthen'd with what apology you think +May make it probable need. + + + +HELENA +What more commands he? + + + +PAROLLES +That, having this obtain'd, you presently +Attend his further pleasure. + + + +HELENA +In every thing I wait upon his will. + + + +PAROLLES +I shall report it so. + + + +HELENA +I pray you. +Exit PAROLLES +Come, sirrah. + + +Exeunt + + +SCENE V. Paris. The KING's palace. +Enter LAFEU and BERTRAM + + +LAFEU +But I hope your lordship thinks not him a soldier. + + + +BERTRAM +Yes, my lord, and of very valiant approof. + + + +LAFEU +You have it from his own deliverance. + + + +BERTRAM +And by other warranted testimony. + + + +LAFEU +Then my dial goes not true: I took this lark for a bunting. + + + +BERTRAM +I do assure you, my lord, he is very great in +knowledge and accordingly valiant. + + + +LAFEU +I have then sinned against his experience and +transgressed against his valour; and my state that +way is dangerous, since I cannot yet find in my +heart to repent. Here he comes: I pray you, make +us friends; I will pursue the amity. + + +Enter PAROLLES + + +PAROLLES +To BERTRAM These things shall be done, sir. + + + +LAFEU +Pray you, sir, who's his tailor? + + + +PAROLLES +Sir? + + + +LAFEU +O, I know him well, I, sir; he, sir, 's a good +workman, a very good tailor. + + + +BERTRAM +Aside to PAROLLES Is she gone to the king? + + + +PAROLLES +She is. + + + +BERTRAM +Will she away to-night? + + + +PAROLLES +As you'll have her. + + + +BERTRAM +I have writ my letters, casketed my treasure, +Given order for our horses; and to-night, +When I should take possession of the bride, +End ere I do begin. + + + +LAFEU +A good traveller is something at the latter end of a +dinner; but one that lies three thirds and uses a +known truth to pass a thousand nothings with, should +be once heard and thrice beaten. God save you, captain. + + + +BERTRAM +Is there any unkindness between my lord and you, monsieur? + + + +PAROLLES +I know not how I have deserved to run into my lord's +displeasure. + + + +LAFEU +You have made shift to run into 't, boots and spurs +and all, like him that leaped into the custard; and +out of it you'll run again, rather than suffer +question for your residence. + + + +BERTRAM +It may be you have mistaken him, my lord. + + + +LAFEU +And shall do so ever, though I took him at 's +prayers. Fare you well, my lord; and believe this +of me, there can be no kernel in this light nut; the +soul of this man is his clothes. Trust him not in +matter of heavy consequence; I have kept of them +tame, and know their natures. Farewell, monsieur: +I have spoken better of you than you have or will to +deserve at my hand; but we must do good against evil. + + +Exit + + +PAROLLES +An idle lord. I swear. + + + +BERTRAM +I think so. + + + +PAROLLES +Why, do you not know him? + + + +BERTRAM +Yes, I do know him well, and common speech +Gives him a worthy pass. Here comes my clog. + + +Enter HELENA + + +HELENA +I have, sir, as I was commanded from you, +Spoke with the king and have procured his leave +For present parting; only he desires +Some private speech with you. + + + +BERTRAM +I shall obey his will. +You must not marvel, Helen, at my course, +Which holds not colour with the time, nor does +The ministration and required office +On my particular. Prepared I was not +For such a business; therefore am I found +So much unsettled: this drives me to entreat you +That presently you take our way for home; +And rather muse than ask why I entreat you, +For my respects are better than they seem +And my appointments have in them a need +Greater than shows itself at the first view +To you that know them not. This to my mother: +Giving a letter +'Twill be two days ere I shall see you, so +I leave you to your wisdom. + + + +HELENA +Sir, I can nothing say, +But that I am your most obedient servant. + + + +BERTRAM +Come, come, no more of that. + + + +HELENA +And ever shall +With true observance seek to eke out that +Wherein toward me my homely stars have fail'd +To equal my great fortune. + + + +BERTRAM +Let that go: +My haste is very great: farewell; hie home. + + + +HELENA +Pray, sir, your pardon. + + + +BERTRAM +Well, what would you say? + + + +HELENA +I am not worthy of the wealth I owe, +Nor dare I say 'tis mine, and yet it is; +But, like a timorous thief, most fain would steal +What law does vouch mine own. + + + +BERTRAM +What would you have? + + + +HELENA +Something; and scarce so much: nothing, indeed. +I would not tell you what I would, my lord: +Faith yes; +Strangers and foes do sunder, and not kiss. + + + +BERTRAM +I pray you, stay not, but in haste to horse. + + + +HELENA +I shall not break your bidding, good my lord. + + + +BERTRAM +Where are my other men, monsieur? Farewell. +Exit HELENA +Go thou toward home; where I will never come +Whilst I can shake my sword or hear the drum. +Away, and for our flight. + + + +PAROLLES +Bravely, coragio! + + +Exeunt + + + + +ACT III + +SCENE I. Florence. The DUKE's palace. +Flourish. Enter the DUKE of Florence attended; +the two Frenchmen, with a troop of soldiers. + + +DUKE +So that from point to point now have you heard +The fundamental reasons of this war, +Whose great decision hath much blood let forth +And more thirsts after. + + + +First Lord +Holy seems the quarrel +Upon your grace's part; black and fearful +On the opposer. + + + +DUKE +Therefore we marvel much our cousin France +Would in so just a business shut his bosom +Against our borrowing prayers. + + + +Second Lord +Good my lord, +The reasons of our state I cannot yield, +But like a common and an outward man, +That the great figure of a council frames +By self-unable motion: therefore dare not +Say what I think of it, since I have found +Myself in my incertain grounds to fail +As often as I guess'd. + + + +DUKE +Be it his pleasure. + + + +First Lord +But I am sure the younger of our nature, +That surfeit on their ease, will day by day +Come here for physic. + + + +DUKE +Welcome shall they be; +And all the honours that can fly from us +Shall on them settle. You know your places well; +When better fall, for your avails they fell: +To-morrow to the field. + + +Flourish. Exeunt + + +SCENE II. Rousillon. The COUNT's palace. +Enter COUNTESS and Clown + + +COUNTESS +It hath happened all as I would have had it, save +that he comes not along with her. + + + +Clown +By my troth, I take my young lord to be a very +melancholy man. + + + +COUNTESS +By what observance, I pray you? + + + +Clown +Why, he will look upon his boot and sing; mend the +ruff and sing; ask questions and sing; pick his +teeth and sing. I know a man that had this trick of +melancholy sold a goodly manor for a song. + + + +COUNTESS +Let me see what he writes, and when he means to come. + + +Opening a letter + + +Clown +I have no mind to Isbel since I was at court: our +old ling and our Isbels o' the country are nothing +like your old ling and your Isbels o' the court: +the brains of my Cupid's knocked out, and I begin to +love, as an old man loves money, with no stomach. + + + +COUNTESS +What have we here? + + + +Clown +E'en that you have there. + + +Exit + + +COUNTESS +Reads I have sent you a daughter-in-law: she hath +recovered the king, and undone me. I have wedded +her, not bedded her; and sworn to make the 'not' +eternal. You shall hear I am run away: know it +before the report come. If there be breadth enough +in the world, I will hold a long distance. My duty +to you. Your unfortunate son, +BERTRAM. +This is not well, rash and unbridled boy. +To fly the favours of so good a king; +To pluck his indignation on thy head +By the misprising of a maid too virtuous +For the contempt of empire. + + +Re-enter Clown + + +Clown +O madam, yonder is heavy news within between two +soldiers and my young lady! + + + +COUNTESS +What is the matter? + + + +Clown +Nay, there is some comfort in the news, some +comfort; your son will not be killed so soon as I +thought he would. + + + +COUNTESS +Why should he be killed? + + + +Clown +So say I, madam, if he run away, as I hear he does: +the danger is in standing to't; that's the loss of +men, though it be the getting of children. Here +they come will tell you more: for my part, I only +hear your son was run away. + + +Exit +Enter HELENA, and two Gentlemen + + +First Gentleman +Save you, good madam. + + + +HELENA +Madam, my lord is gone, for ever gone. + + + +Second Gentleman +Do not say so. + + + +COUNTESS +Think upon patience. Pray you, gentlemen, +I have felt so many quirks of joy and grief, +That the first face of neither, on the start, +Can woman me unto't: where is my son, I pray you? + + + +Second Gentleman +Madam, he's gone to serve the duke of Florence: +We met him thitherward; for thence we came, +And, after some dispatch in hand at court, +Thither we bend again. + + + +HELENA +Look on his letter, madam; here's my passport. +Reads +When thou canst get the ring upon my finger which +never shall come off, and show me a child begotten +of thy body that I am father to, then call me +husband: but in such a 'then' I write a 'never.' +This is a dreadful sentence. + + + +COUNTESS +Brought you this letter, gentlemen? + + + +First Gentleman +Ay, madam; +And for the contents' sake are sorry for our pain. + + + +COUNTESS +I prithee, lady, have a better cheer; +If thou engrossest all the griefs are thine, +Thou robb'st me of a moiety: he was my son; +But I do wash his name out of my blood, +And thou art all my child. Towards Florence is he? + + + +Second Gentleman +Ay, madam. + + + +COUNTESS +And to be a soldier? + + + +Second Gentleman +Such is his noble purpose; and believe 't, +The duke will lay upon him all the honour +That good convenience claims. + + + +COUNTESS +Return you thither? + + + +First Gentleman +Ay, madam, with the swiftest wing of speed. + + + +HELENA +Reads Till I have no wife I have nothing in France. +'Tis bitter. + + + +COUNTESS +Find you that there? + + + +HELENA +Ay, madam. + + + +First Gentleman +'Tis but the boldness of his hand, haply, which his +heart was not consenting to. + + + +COUNTESS +Nothing in France, until he have no wife! +There's nothing here that is too good for him +But only she; and she deserves a lord +That twenty such rude boys might tend upon +And call her hourly mistress. Who was with him? + + + +First Gentleman +A servant only, and a gentleman +Which I have sometime known. + + + +COUNTESS +Parolles, was it not? + + + +First Gentleman +Ay, my good lady, he. + + + +COUNTESS +A very tainted fellow, and full of wickedness. +My son corrupts a well-derived nature +With his inducement. + + + +First Gentleman +Indeed, good lady, +The fellow has a deal of that too much, +Which holds him much to have. + + + +COUNTESS +You're welcome, gentlemen. +I will entreat you, when you see my son, +To tell him that his sword can never win +The honour that he loses: more I'll entreat you +Written to bear along. + + + +Second Gentleman +We serve you, madam, +In that and all your worthiest affairs. + + + +COUNTESS +Not so, but as we change our courtesies. +Will you draw near! + + +Exeunt COUNTESS and Gentlemen + + +HELENA +'Till I have no wife, I have nothing in France.' +Nothing in France, until he has no wife! +Thou shalt have none, Rousillon, none in France; +Then hast thou all again. Poor lord! is't I +That chase thee from thy country and expose +Those tender limbs of thine to the event +Of the none-sparing war? and is it I +That drive thee from the sportive court, where thou +Wast shot at with fair eyes, to be the mark +Of smoky muskets? O you leaden messengers, +That ride upon the violent speed of fire, +Fly with false aim; move the still-peering air, +That sings with piercing; do not touch my lord. +Whoever shoots at him, I set him there; +Whoever charges on his forward breast, +I am the caitiff that do hold him to't; +And, though I kill him not, I am the cause +His death was so effected: better 'twere +I met the ravin lion when he roar'd +With sharp constraint of hunger; better 'twere +That all the miseries which nature owes +Were mine at once. No, come thou home, Rousillon, +Whence honour but of danger wins a scar, +As oft it loses all: I will be gone; +My being here it is that holds thee hence: +Shall I stay here to do't? no, no, although +The air of paradise did fan the house +And angels officed all: I will be gone, +That pitiful rumour may report my flight, +To consolate thine ear. Come, night; end, day! +For with the dark, poor thief, I'll steal away. + + +Exit + + +SCENE III. Florence. Before the DUKE's palace. +Flourish. Enter the DUKE of Florence, BERTRAM, +PAROLLES, Soldiers, Drum, and Trumpets + + +DUKE +The general of our horse thou art; and we, +Great in our hope, lay our best love and credence +Upon thy promising fortune. + + + +BERTRAM +Sir, it is +A charge too heavy for my strength, but yet +We'll strive to bear it for your worthy sake +To the extreme edge of hazard. + + + +DUKE +Then go thou forth; +And fortune play upon thy prosperous helm, +As thy auspicious mistress! + + + +BERTRAM +This very day, +Great Mars, I put myself into thy file: +Make me but like my thoughts, and I shall prove +A lover of thy drum, hater of love. + + +Exeunt + + +SCENE IV. Rousillon. The COUNT's palace. +Enter COUNTESS and Steward + + +COUNTESS +Alas! and would you take the letter of her? +Might you not know she would do as she has done, +By sending me a letter? Read it again. + + + +Steward +Reads +I am Saint Jaques' pilgrim, thither gone: +Ambitious love hath so in me offended, +That barefoot plod I the cold ground upon, +With sainted vow my faults to have amended. +Write, write, that from the bloody course of war +My dearest master, your dear son, may hie: +Bless him at home in peace, whilst I from far +His name with zealous fervor sanctify: +His taken labours bid him me forgive; +I, his despiteful Juno, sent him forth +From courtly friends, with camping foes to live, +Where death and danger dogs the heels of worth: +He is too good and fair for death and me: +Whom I myself embrace, to set him free. + + + +COUNTESS +Ah, what sharp stings are in her mildest words! +Rinaldo, you did never lack advice so much, +As letting her pass so: had I spoke with her, +I could have well diverted her intents, +Which thus she hath prevented. + + + +Steward +Pardon me, madam: +If I had given you this at over-night, +She might have been o'erta'en; and yet she writes, +Pursuit would be but vain. + + + +COUNTESS +What angel shall +Bless this unworthy husband? he cannot thrive, +Unless her prayers, whom heaven delights to hear +And loves to grant, reprieve him from the wrath +Of greatest justice. Write, write, Rinaldo, +To this unworthy husband of his wife; +Let every word weigh heavy of her worth +That he does weigh too light: my greatest grief. +Though little he do feel it, set down sharply. +Dispatch the most convenient messenger: +When haply he shall hear that she is gone, +He will return; and hope I may that she, +Hearing so much, will speed her foot again, +Led hither by pure love: which of them both +Is dearest to me. I have no skill in sense +To make distinction: provide this messenger: +My heart is heavy and mine age is weak; +Grief would have tears, and sorrow bids me speak. + + +Exeunt + + +SCENE V. Florence. Without the walls. A tucket afar off. +Enter an old Widow of Florence, DIANA, VIOLENTA, +and MARIANA, with other Citizens + + +Widow +Nay, come; for if they do approach the city, we +shall lose all the sight. + + + +DIANA +They say the French count has done most honourable service. + + + +Widow +It is reported that he has taken their greatest +commander; and that with his own hand he slew the +duke's brother. +Tucket +We have lost our labour; they are gone a contrary +way: hark! you may know by their trumpets. + + + +MARIANA +Come, let's return again, and suffice ourselves with +the report of it. Well, Diana, take heed of this +French earl: the honour of a maid is her name; and +no legacy is so rich as honesty. + + + +Widow +I have told my neighbour how you have been solicited +by a gentleman his companion. + + + +MARIANA +I know that knave; hang him! one Parolles: a +filthy officer he is in those suggestions for the +young earl. Beware of them, Diana; their promises, +enticements, oaths, tokens, and all these engines of +lust, are not the things they go under: many a maid +hath been seduced by them; and the misery is, +example, that so terrible shows in the wreck of +maidenhood, cannot for all that dissuade succession, +but that they are limed with the twigs that threaten +them. I hope I need not to advise you further; but +I hope your own grace will keep you where you are, +though there were no further danger known but the +modesty which is so lost. + + + +DIANA +You shall not need to fear me. + + + +Widow +I hope so. +Enter HELENA, disguised like a Pilgrim +Look, here comes a pilgrim: I know she will lie at +my house; thither they send one another: I'll +question her. God save you, pilgrim! whither are you bound? + + + +HELENA +To Saint Jaques le Grand. +Where do the palmers lodge, I do beseech you? + + + +Widow +At the Saint Francis here beside the port. + + + +HELENA +Is this the way? + + + +Widow +Ay, marry, is't. +A march afar +Hark you! they come this way. +If you will tarry, holy pilgrim, +But till the troops come by, +I will conduct you where you shall be lodged; +The rather, for I think I know your hostess +As ample as myself. + + + +HELENA +Is it yourself? + + + +Widow +If you shall please so, pilgrim. + + + +HELENA +I thank you, and will stay upon your leisure. + + + +Widow +You came, I think, from France? + + + +HELENA +I did so. + + + +Widow +Here you shall see a countryman of yours +That has done worthy service. + + + +HELENA +His name, I pray you. + + + +DIANA +The Count Rousillon: know you such a one? + + + +HELENA +But by the ear, that hears most nobly of him: +His face I know not. + + + +DIANA +Whatsome'er he is, +He's bravely taken here. He stole from France, +As 'tis reported, for the king had married him +Against his liking: think you it is so? + + + +HELENA +Ay, surely, mere the truth: I know his lady. + + + +DIANA +There is a gentleman that serves the count +Reports but coarsely of her. + + + +HELENA +What's his name? + + + +DIANA +Monsieur Parolles. + + + +HELENA +O, I believe with him, +In argument of praise, or to the worth +Of the great count himself, she is too mean +To have her name repeated: all her deserving +Is a reserved honesty, and that +I have not heard examined. + + + +DIANA +Alas, poor lady! +'Tis a hard bondage to become the wife +Of a detesting lord. + + + +Widow +I warrant, good creature, wheresoe'er she is, +Her heart weighs sadly: this young maid might do her +A shrewd turn, if she pleased. + + + +HELENA +How do you mean? +May be the amorous count solicits her +In the unlawful purpose. + + + +Widow +He does indeed; +And brokes with all that can in such a suit +Corrupt the tender honour of a maid: +But she is arm'd for him and keeps her guard +In honestest defence. + + + +MARIANA +The gods forbid else! + + + +Widow +So, now they come: +Drum and Colours +Enter BERTRAM, PAROLLES, and the whole army +That is Antonio, the duke's eldest son; +That, Escalus. + + + +HELENA +Which is the Frenchman? + + + +DIANA +He; +That with the plume: 'tis a most gallant fellow. +I would he loved his wife: if he were honester +He were much goodlier: is't not a handsome gentleman? + + + +HELENA +I like him well. + + + +DIANA +'Tis pity he is not honest: yond's that same knave +That leads him to these places: were I his lady, +I would Poison that vile rascal. + + + +HELENA +Which is he? + + + +DIANA +That jack-an-apes with scarfs: why is he melancholy? + + + +HELENA +Perchance he's hurt i' the battle. + + + +PAROLLES +Lose our drum! well. + + + +MARIANA +He's shrewdly vexed at something: look, he has spied us. + + + +Widow +Marry, hang you! + + + +MARIANA +And your courtesy, for a ring-carrier! + + +Exeunt BERTRAM, PAROLLES, and army + + +Widow +The troop is past. Come, pilgrim, I will bring you +Where you shall host: of enjoin'd penitents +There's four or five, to great Saint Jaques bound, +Already at my house. + + + +HELENA +I humbly thank you: +Please it this matron and this gentle maid +To eat with us to-night, the charge and thanking +Shall be for me; and, to requite you further, +I will bestow some precepts of this virgin +Worthy the note. + + + +BOTH +We'll take your offer kindly. + + +Exeunt + + +SCENE VI. Camp before Florence. +Enter BERTRAM and the two French Lords + + +Second Lord +Nay, good my lord, put him to't; let him have his +way. + + + +First Lord +If your lordship find him not a hilding, hold me no +more in your respect. + + + +Second Lord +On my life, my lord, a bubble. + + + +BERTRAM +Do you think I am so far deceived in him? + + + +Second Lord +Believe it, my lord, in mine own direct knowledge, +without any malice, but to speak of him as my +kinsman, he's a most notable coward, an infinite and +endless liar, an hourly promise-breaker, the owner +of no one good quality worthy your lordship's +entertainment. + + + +First Lord +It were fit you knew him; lest, reposing too far in +his virtue, which he hath not, he might at some +great and trusty business in a main danger fail you. + + + +BERTRAM +I would I knew in what particular action to try him. + + + +First Lord +None better than to let him fetch off his drum, +which you hear him so confidently undertake to do. + + + +Second Lord +I, with a troop of Florentines, will suddenly +surprise him; such I will have, whom I am sure he +knows not from the enemy: we will bind and hoodwink +him so, that he shall suppose no other but that he +is carried into the leaguer of the adversaries, when +we bring him to our own tents. Be but your lordship +present at his examination: if he do not, for the +promise of his life and in the highest compulsion of +base fear, offer to betray you and deliver all the +intelligence in his power against you, and that with +the divine forfeit of his soul upon oath, never +trust my judgment in any thing. + + + +First Lord +O, for the love of laughter, let him fetch his drum; +he says he has a stratagem for't: when your +lordship sees the bottom of his success in't, and to +what metal this counterfeit lump of ore will be +melted, if you give him not John Drum's +entertainment, your inclining cannot be removed. +Here he comes. + + +Enter PAROLLES + + +Second Lord +Aside to BERTRAM O, for the love of laughter, +hinder not the honour of his design: let him fetch +off his drum in any hand. + + + +BERTRAM +How now, monsieur! this drum sticks sorely in your +disposition. + + + +First Lord +A pox on't, let it go; 'tis but a drum. + + + +PAROLLES +'But a drum'! is't 'but a drum'? A drum so lost! +There was excellent command,--to charge in with our +horse upon our own wings, and to rend our own soldiers! + + + +First Lord +That was not to be blamed in the command of the +service: it was a disaster of war that Caesar +himself could not have prevented, if he had been +there to command. + + + +BERTRAM +Well, we cannot greatly condemn our success: some +dishonour we had in the loss of that drum; but it is +not to be recovered. + + + +PAROLLES +It might have been recovered. + + + +BERTRAM +It might; but it is not now. + + + +PAROLLES +It is to be recovered: but that the merit of +service is seldom attributed to the true and exact +performer, I would have that drum or another, or +'hic jacet.' + + + +BERTRAM +Why, if you have a stomach, to't, monsieur: if you +think your mystery in stratagem can bring this +instrument of honour again into his native quarter, +be magnanimous in the enterprise and go on; I will +grace the attempt for a worthy exploit: if you +speed well in it, the duke shall both speak of it. +and extend to you what further becomes his +greatness, even to the utmost syllable of your +worthiness. + + + +PAROLLES +By the hand of a soldier, I will undertake it. + + + +BERTRAM +But you must not now slumber in it. + + + +PAROLLES +I'll about it this evening: and I will presently +pen down my dilemmas, encourage myself in my +certainty, put myself into my mortal preparation; +and by midnight look to hear further from me. + + + +BERTRAM +May I be bold to acquaint his grace you are gone about it? + + + +PAROLLES +I know not what the success will be, my lord; but +the attempt I vow. + + + +BERTRAM +I know thou'rt valiant; and, to the possibility of +thy soldiership, will subscribe for thee. Farewell. + + + +PAROLLES +I love not many words. + + +Exit + + +Second Lord +No more than a fish loves water. Is not this a +strange fellow, my lord, that so confidently seems +to undertake this business, which he knows is not to +be done; damns himself to do and dares better be +damned than to do't? + + + +First Lord +You do not know him, my lord, as we do: certain it +is that he will steal himself into a man's favour and +for a week escape a great deal of discoveries; but +when you find him out, you have him ever after. + + + +BERTRAM +Why, do you think he will make no deed at all of +this that so seriously he does address himself unto? + + + +Second Lord +None in the world; but return with an invention and +clap upon you two or three probable lies: but we +have almost embossed him; you shall see his fall +to-night; for indeed he is not for your lordship's respect. + + + +First Lord +We'll make you some sport with the fox ere we case +him. He was first smoked by the old lord Lafeu: +when his disguise and he is parted, tell me what a +sprat you shall find him; which you shall see this +very night. + + + +Second Lord +I must go look my twigs: he shall be caught. + + + +BERTRAM +Your brother he shall go along with me. + + + +Second Lord +As't please your lordship: I'll leave you. + + +Exit + + +BERTRAM +Now will I lead you to the house, and show you +The lass I spoke of. + + + +First Lord +But you say she's honest. + + + +BERTRAM +That's all the fault: I spoke with her but once +And found her wondrous cold; but I sent to her, +By this same coxcomb that we have i' the wind, +Tokens and letters which she did re-send; +And this is all I have done. She's a fair creature: +Will you go see her? + + + +First Lord +With all my heart, my lord. + + +Exeunt + + +SCENE VII. Florence. The Widow's house. +Enter HELENA and Widow + + +HELENA +If you misdoubt me that I am not she, +I know not how I shall assure you further, +But I shall lose the grounds I work upon. + + + +Widow +Though my estate be fallen, I was well born, +Nothing acquainted with these businesses; +And would not put my reputation now +In any staining act. + + + +HELENA +Nor would I wish you. +First, give me trust, the count he is my husband, +And what to your sworn counsel I have spoken +Is so from word to word; and then you cannot, +By the good aid that I of you shall borrow, +Err in bestowing it. + + + +Widow +I should believe you: +For you have show'd me that which well approves +You're great in fortune. + + + +HELENA +Take this purse of gold, +And let me buy your friendly help thus far, +Which I will over-pay and pay again +When I have found it. The count he wooes your daughter, +Lays down his wanton siege before her beauty, +Resolved to carry her: let her in fine consent, +As we'll direct her how 'tis best to bear it. +Now his important blood will nought deny +That she'll demand: a ring the county wears, +That downward hath succeeded in his house +From son to son, some four or five descents +Since the first father wore it: this ring he holds +In most rich choice; yet in his idle fire, +To buy his will, it would not seem too dear, +Howe'er repented after. + + + +Widow +Now I see +The bottom of your purpose. + + + +HELENA +You see it lawful, then: it is no more, +But that your daughter, ere she seems as won, +Desires this ring; appoints him an encounter; +In fine, delivers me to fill the time, +Herself most chastely absent: after this, +To marry her, I'll add three thousand crowns +To what is passed already. + + + +Widow +I have yielded: +Instruct my daughter how she shall persever, +That time and place with this deceit so lawful +May prove coherent. Every night he comes +With musics of all sorts and songs composed +To her unworthiness: it nothing steads us +To chide him from our eaves; for he persists +As if his life lay on't. + + + +HELENA +Why then to-night +Let us assay our plot; which, if it speed, +Is wicked meaning in a lawful deed +And lawful meaning in a lawful act, +Where both not sin, and yet a sinful fact: +But let's about it. + + +Exeunt + + + + +ACT IV + +SCENE I. Without the Florentine camp. +Enter Second French Lord, with five or six other +Soldiers in ambush + + +Second Lord +He can come no other way but by this hedge-corner. +When you sally upon him, speak what terrible +language you will: though you understand it not +yourselves, no matter; for we must not seem to +understand him, unless some one among us whom we +must produce for an interpreter. + + + +First Soldier +Good captain, let me be the interpreter. + + + +Second Lord +Art not acquainted with him? knows he not thy voice? + + + +First Soldier +No, sir, I warrant you. + + + +Second Lord +But what linsey-woolsey hast thou to speak to us again? + + + +First Soldier +E'en such as you speak to me. + + + +Second Lord +He must think us some band of strangers i' the +adversary's entertainment. Now he hath a smack of +all neighbouring languages; therefore we must every +one be a man of his own fancy, not to know what we +speak one to another; so we seem to know, is to +know straight our purpose: choughs' language, +gabble enough, and good enough. As for you, +interpreter, you must seem very politic. But couch, +ho! here he comes, to beguile two hours in a sleep, +and then to return and swear the lies he forges. + + +Enter PAROLLES + + +PAROLLES +Ten o'clock: within these three hours 'twill be +time enough to go home. What shall I say I have +done? It must be a very plausive invention that +carries it: they begin to smoke me; and disgraces +have of late knocked too often at my door. I find +my tongue is too foolhardy; but my heart hath the +fear of Mars before it and of his creatures, not +daring the reports of my tongue. + + + +Second Lord +This is the first truth that e'er thine own tongue +was guilty of. + + + +PAROLLES +What the devil should move me to undertake the +recovery of this drum, being not ignorant of the +impossibility, and knowing I had no such purpose? I +must give myself some hurts, and say I got them in +exploit: yet slight ones will not carry it; they +will say, 'Came you off with so little?' and great +ones I dare not give. Wherefore, what's the +instance? Tongue, I must put you into a +butter-woman's mouth and buy myself another of +Bajazet's mule, if you prattle me into these perils. + + + +Second Lord +Is it possible he should know what he is, and be +that he is? + + + +PAROLLES +I would the cutting of my garments would serve the +turn, or the breaking of my Spanish sword. + + + +Second Lord +We cannot afford you so. + + + +PAROLLES +Or the baring of my beard; and to say it was in +stratagem. + + + +Second Lord +'Twould not do. + + + +PAROLLES +Or to drown my clothes, and say I was stripped. + + + +Second Lord +Hardly serve. + + + +PAROLLES +Though I swore I leaped from the window of the citadel. + + + +Second Lord +How deep? + + + +PAROLLES +Thirty fathom. + + + +Second Lord +Three great oaths would scarce make that be believed. + + + +PAROLLES +I would I had any drum of the enemy's: I would swear +I recovered it. + + + +Second Lord +You shall hear one anon. + + + +PAROLLES +A drum now of the enemy's,-- + + +Alarum within + + +Second Lord +Throca movousus, cargo, cargo, cargo. + + + +All +Cargo, cargo, cargo, villiando par corbo, cargo. + + + +PAROLLES +O, ransom, ransom! do not hide mine eyes. + + +They seize and blindfold him + + +First Soldier +Boskos thromuldo boskos. + + + +PAROLLES +I know you are the Muskos' regiment: +And I shall lose my life for want of language; +If there be here German, or Dane, low Dutch, +Italian, or French, let him speak to me; I'll +Discover that which shall undo the Florentine. + + + +First Soldier +Boskos vauvado: I understand thee, and can speak +thy tongue. Kerely bonto, sir, betake thee to thy +faith, for seventeen poniards are at thy bosom. + + + +PAROLLES +O! + + + +First Soldier +O, pray, pray, pray! Manka revania dulche. + + + +Second Lord +Oscorbidulchos volivorco. + + + +First Soldier +The general is content to spare thee yet; +And, hoodwink'd as thou art, will lead thee on +To gather from thee: haply thou mayst inform +Something to save thy life. + + + +PAROLLES +O, let me live! +And all the secrets of our camp I'll show, +Their force, their purposes; nay, I'll speak that +Which you will wonder at. + + + +First Soldier +But wilt thou faithfully? + + + +PAROLLES +If I do not, damn me. + + + +First Soldier +Acordo linta. +Come on; thou art granted space. + + +Exit, with PAROLLES guarded. A short alarum within + + +Second Lord +Go, tell the Count Rousillon, and my brother, +We have caught the woodcock, and will keep him muffled +Till we do hear from them. + + + +Second Soldier +Captain, I will. + + + +Second Lord +A' will betray us all unto ourselves: +Inform on that. + + + +Second Soldier +So I will, sir. + + + +Second Lord +Till then I'll keep him dark and safely lock'd. + + +Exeunt + + +SCENE II. Florence. The Widow's house. +Enter BERTRAM and DIANA + + +BERTRAM +They told me that your name was Fontibell. + + + +DIANA +No, my good lord, Diana. + + + +BERTRAM +Titled goddess; +And worth it, with addition! But, fair soul, +In your fine frame hath love no quality? +If quick fire of youth light not your mind, +You are no maiden, but a monument: +When you are dead, you should be such a one +As you are now, for you are cold and stem; +And now you should be as your mother was +When your sweet self was got. + + + +DIANA +She then was honest. + + + +BERTRAM +So should you be. + + + +DIANA +No: +My mother did but duty; such, my lord, +As you owe to your wife. + + + +BERTRAM +No more o' that; +I prithee, do not strive against my vows: +I was compell'd to her; but I love thee +By love's own sweet constraint, and will for ever +Do thee all rights of service. + + + +DIANA +Ay, so you serve us +Till we serve you; but when you have our roses, +You barely leave our thorns to prick ourselves +And mock us with our bareness. + + + +BERTRAM +How have I sworn! + + + +DIANA +'Tis not the many oaths that makes the truth, +But the plain single vow that is vow'd true. +What is not holy, that we swear not by, +But take the High'st to witness: then, pray you, tell me, +If I should swear by God's great attributes, +I loved you dearly, would you believe my oaths, +When I did love you ill? This has no holding, +To swear by him whom I protest to love, +That I will work against him: therefore your oaths +Are words and poor conditions, but unseal'd, +At least in my opinion. + + + +BERTRAM +Change it, change it; +Be not so holy-cruel: love is holy; +And my integrity ne'er knew the crafts +That you do charge men with. Stand no more off, +But give thyself unto my sick desires, +Who then recover: say thou art mine, and ever +My love as it begins shall so persever. + + + +DIANA +I see that men make ropes in such a scarre +That we'll forsake ourselves. Give me that ring. + + + +BERTRAM +I'll lend it thee, my dear; but have no power +To give it from me. + + + +DIANA +Will you not, my lord? + + + +BERTRAM +It is an honour 'longing to our house, +Bequeathed down from many ancestors; +Which were the greatest obloquy i' the world +In me to lose. + + + +DIANA +Mine honour's such a ring: +My chastity's the jewel of our house, +Bequeathed down from many ancestors; +Which were the greatest obloquy i' the world +In me to lose: thus your own proper wisdom +Brings in the champion Honour on my part, +Against your vain assault. + + + +BERTRAM +Here, take my ring: +My house, mine honour, yea, my life, be thine, +And I'll be bid by thee. + + + +DIANA +When midnight comes, knock at my chamber-window: +I'll order take my mother shall not hear. +Now will I charge you in the band of truth, +When you have conquer'd my yet maiden bed, +Remain there but an hour, nor speak to me: +My reasons are most strong; and you shall know them +When back again this ring shall be deliver'd: +And on your finger in the night I'll put +Another ring, that what in time proceeds +May token to the future our past deeds. +Adieu, till then; then, fail not. You have won +A wife of me, though there my hope be done. + + + +BERTRAM +A heaven on earth I have won by wooing thee. + + +Exit + + +DIANA +For which live long to thank both heaven and me! +You may so in the end. +My mother told me just how he would woo, +As if she sat in 's heart; she says all men +Have the like oaths: he had sworn to marry me +When his wife's dead; therefore I'll lie with him +When I am buried. Since Frenchmen are so braid, +Marry that will, I live and die a maid: +Only in this disguise I think't no sin +To cozen him that would unjustly win. + + +Exit + + +SCENE III. The Florentine camp. +Enter the two French Lords and some two or three Soldiers + + +First Lord +You have not given him his mother's letter? + + + +Second Lord +I have delivered it an hour since: there is +something in't that stings his nature; for on the +reading it he changed almost into another man. + + + +First Lord +He has much worthy blame laid upon him for shaking +off so good a wife and so sweet a lady. + + + +Second Lord +Especially he hath incurred the everlasting +displeasure of the king, who had even tuned his +bounty to sing happiness to him. I will tell you a +thing, but you shall let it dwell darkly with you. + + + +First Lord +When you have spoken it, 'tis dead, and I am the +grave of it. + + + +Second Lord +He hath perverted a young gentlewoman here in +Florence, of a most chaste renown; and this night he +fleshes his will in the spoil of her honour: he hath +given her his monumental ring, and thinks himself +made in the unchaste composition. + + + +First Lord +Now, God delay our rebellion! as we are ourselves, +what things are we! + + + +Second Lord +Merely our own traitors. And as in the common course +of all treasons, we still see them reveal +themselves, till they attain to their abhorred ends, +so he that in this action contrives against his own +nobility, in his proper stream o'erflows himself. + + + +First Lord +Is it not meant damnable in us, to be trumpeters of +our unlawful intents? We shall not then have his +company to-night? + + + +Second Lord +Not till after midnight; for he is dieted to his hour. + + + +First Lord +That approaches apace; I would gladly have him see +his company anatomized, that he might take a measure +of his own judgments, wherein so curiously he had +set this counterfeit. + + + +Second Lord +We will not meddle with him till he come; for his +presence must be the whip of the other. + + + +First Lord +In the mean time, what hear you of these wars? + + + +Second Lord +I hear there is an overture of peace. + + + +First Lord +Nay, I assure you, a peace concluded. + + + +Second Lord +What will Count Rousillon do then? will he travel +higher, or return again into France? + + + +First Lord +I perceive, by this demand, you are not altogether +of his council. + + + +Second Lord +Let it be forbid, sir; so should I be a great deal +of his act. + + + +First Lord +Sir, his wife some two months since fled from his +house: her pretence is a pilgrimage to Saint Jaques +le Grand; which holy undertaking with most austere +sanctimony she accomplished; and, there residing the +tenderness of her nature became as a prey to her +grief; in fine, made a groan of her last breath, and +now she sings in heaven. + + + +Second Lord +How is this justified? + + + +First Lord +The stronger part of it by her own letters, which +makes her story true, even to the point of her +death: her death itself, which could not be her +office to say is come, was faithfully confirmed by +the rector of the place. + + + +Second Lord +Hath the count all this intelligence? + + + +First Lord +Ay, and the particular confirmations, point from +point, so to the full arming of the verity. + + + +Second Lord +I am heartily sorry that he'll be glad of this. + + + +First Lord +How mightily sometimes we make us comforts of our losses! + + + +Second Lord +And how mightily some other times we drown our gain +in tears! The great dignity that his valour hath +here acquired for him shall at home be encountered +with a shame as ample. + + + +First Lord +The web of our life is of a mingled yarn, good and +ill together: our virtues would be proud, if our +faults whipped them not; and our crimes would +despair, if they were not cherished by our virtues. +Enter a Messenger +How now! where's your master? + + + +Servant +He met the duke in the street, sir, of whom he hath +taken a solemn leave: his lordship will next +morning for France. The duke hath offered him +letters of commendations to the king. + + + +Second Lord +They shall be no more than needful there, if they +were more than they can commend. + + + +First Lord +They cannot be too sweet for the king's tartness. +Here's his lordship now. +Enter BERTRAM +How now, my lord! is't not after midnight? + + + +BERTRAM +I have to-night dispatched sixteen businesses, a +month's length a-piece, by an abstract of success: +I have congied with the duke, done my adieu with his +nearest; buried a wife, mourned for her; writ to my +lady mother I am returning; entertained my convoy; +and between these main parcels of dispatch effected +many nicer needs; the last was the greatest, but +that I have not ended yet. + + + +Second Lord +If the business be of any difficulty, and this +morning your departure hence, it requires haste of +your lordship. + + + +BERTRAM +I mean, the business is not ended, as fearing to +hear of it hereafter. But shall we have this +dialogue between the fool and the soldier? Come, +bring forth this counterfeit module, he has deceived +me, like a double-meaning prophesier. + + + +Second Lord +Bring him forth: has sat i' the stocks all night, +poor gallant knave. + + + +BERTRAM +No matter: his heels have deserved it, in usurping +his spurs so long. How does he carry himself? + + + +Second Lord +I have told your lordship already, the stocks carry +him. But to answer you as you would be understood; +he weeps like a wench that had shed her milk: he +hath confessed himself to Morgan, whom he supposes +to be a friar, from the time of his remembrance to +this very instant disaster of his setting i' the +stocks: and what think you he hath confessed? + + + +BERTRAM +Nothing of me, has a'? + + + +Second Lord +His confession is taken, and it shall be read to his +face: if your lordship be in't, as I believe you +are, you must have the patience to hear it. + + +Enter PAROLLES guarded, and First Soldier + + +BERTRAM +A plague upon him! muffled! he can say nothing of +me: hush, hush! + + + +First Lord +Hoodman comes! Portotartarosa + + + +First Soldier +He calls for the tortures: what will you say +without 'em? + + + +PAROLLES +I will confess what I know without constraint: if +ye pinch me like a pasty, I can say no more. + + + +First Soldier +Bosko chimurcho. + + + +First Lord +Boblibindo chicurmurco. + + + +First Soldier +You are a merciful general. Our general bids you +answer to what I shall ask you out of a note. + + + +PAROLLES +And truly, as I hope to live. + + + +First Soldier +Reads 'First demand of him how many horse the +duke is strong.' What say you to that? + + + +PAROLLES +Five or six thousand; but very weak and +unserviceable: the troops are all scattered, and +the commanders very poor rogues, upon my reputation +and credit and as I hope to live. + + + +First Soldier +Shall I set down your answer so? + + + +PAROLLES +Do: I'll take the sacrament on't, how and which way you will. + + + +BERTRAM +All's one to him. What a past-saving slave is this! + + + +First Lord +You're deceived, my lord: this is Monsieur +Parolles, the gallant militarist,--that was his own +phrase,--that had the whole theoric of war in the +knot of his scarf, and the practise in the chape of +his dagger. + + + +Second Lord +I will never trust a man again for keeping his sword +clean. nor believe he can have every thing in him +by wearing his apparel neatly. + + + +First Soldier +Well, that's set down. + + + +PAROLLES +Five or six thousand horse, I said,-- I will say +true,--or thereabouts, set down, for I'll speak truth. + + + +First Lord +He's very near the truth in this. + + + +BERTRAM +But I con him no thanks for't, in the nature he +delivers it. + + + +PAROLLES +Poor rogues, I pray you, say. + + + +First Soldier +Well, that's set down. + + + +PAROLLES +I humbly thank you, sir: a truth's a truth, the +rogues are marvellous poor. + + + +First Soldier +Reads 'Demand of him, of what strength they are +a-foot.' What say you to that? + + + +PAROLLES +By my troth, sir, if I were to live this present +hour, I will tell true. Let me see: Spurio, a +hundred and fifty; Sebastian, so many; Corambus, so +many; Jaques, so many; Guiltian, Cosmo, Lodowick, +and Gratii, two hundred and fifty each; mine own +company, Chitopher, Vaumond, Bentii, two hundred and +fifty each: so that the muster-file, rotten and +sound, upon my life, amounts not to fifteen thousand +poll; half of the which dare not shake snow from off +their cassocks, lest they shake themselves to pieces. + + + +BERTRAM +What shall be done to him? + + + +First Lord +Nothing, but let him have thanks. Demand of him my +condition, and what credit I have with the duke. + + + +First Soldier +Well, that's set down. +Reads +'You shall demand of him, whether one Captain Dumain +be i' the camp, a Frenchman; what his reputation is +with the duke; what his valour, honesty, and +expertness in wars; or whether he thinks it were not +possible, with well-weighing sums of gold, to +corrupt him to revolt.' What say you to this? what +do you know of it? + + + +PAROLLES +I beseech you, let me answer to the particular of +the inter'gatories: demand them singly. + + + +First Soldier +Do you know this Captain Dumain? + + + +PAROLLES +I know him: a' was a botcher's 'prentice in Paris, +from whence he was whipped for getting the shrieve's +fool with child,--a dumb innocent, that could not +say him nay. + + + +BERTRAM +Nay, by your leave, hold your hands; though I know +his brains are forfeit to the next tile that falls. + + + +First Soldier +Well, is this captain in the duke of Florence's camp? + + + +PAROLLES +Upon my knowledge, he is, and lousy. + + + +First Lord +Nay look not so upon me; we shall hear of your +lordship anon. + + + +First Soldier +What is his reputation with the duke? + + + +PAROLLES +The duke knows him for no other but a poor officer +of mine; and writ to me this other day to turn him +out o' the band: I think I have his letter in my pocket. + + + +First Soldier +Marry, we'll search. + + + +PAROLLES +In good sadness, I do not know; either it is there, +or it is upon a file with the duke's other letters +in my tent. + + + +First Soldier +Here 'tis; here's a paper: shall I read it to you? + + + +PAROLLES +I do not know if it be it or no. + + + +BERTRAM +Our interpreter does it well. + + + +First Lord +Excellently. + + + +First Soldier +Reads 'Dian, the count's a fool, and full of gold,'-- + + + +PAROLLES +That is not the duke's letter, sir; that is an +advertisement to a proper maid in Florence, one +Diana, to take heed of the allurement of one Count +Rousillon, a foolish idle boy, but for all that very +ruttish: I pray you, sir, put it up again. + + + +First Soldier +Nay, I'll read it first, by your favour. + + + +PAROLLES +My meaning in't, I protest, was very honest in the +behalf of the maid; for I knew the young count to be +a dangerous and lascivious boy, who is a whale to +virginity and devours up all the fry it finds. + + + +BERTRAM +Damnable both-sides rogue! + + + +First Soldier +Reads 'When he swears oaths, bid him drop gold, and take it; +After he scores, he never pays the score: +Half won is match well made; match, and well make it; +He ne'er pays after-debts, take it before; +And say a soldier, Dian, told thee this, +Men are to mell with, boys are not to kiss: +For count of this, the count's a fool, I know it, +Who pays before, but not when he does owe it. +Thine, as he vowed to thee in thine ear, +PAROLLES.' + + + +BERTRAM +He shall be whipped through the army with this rhyme +in's forehead. + + + +Second Lord +This is your devoted friend, sir, the manifold +linguist and the armipotent soldier. + + + +BERTRAM +I could endure any thing before but a cat, and now +he's a cat to me. + + + +First Soldier +I perceive, sir, by the general's looks, we shall be +fain to hang you. + + + +PAROLLES +My life, sir, in any case: not that I am afraid to +die; but that, my offences being many, I would +repent out the remainder of nature: let me live, +sir, in a dungeon, i' the stocks, or any where, so I may live. + + + +First Soldier +We'll see what may be done, so you confess freely; +therefore, once more to this Captain Dumain: you +have answered to his reputation with the duke and to +his valour: what is his honesty? + + + +PAROLLES +He will steal, sir, an egg out of a cloister: for +rapes and ravishments he parallels Nessus: he +professes not keeping of oaths; in breaking 'em he +is stronger than Hercules: he will lie, sir, with +such volubility, that you would think truth were a +fool: drunkenness is his best virtue, for he will +be swine-drunk; and in his sleep he does little +harm, save to his bed-clothes about him; but they +know his conditions and lay him in straw. I have but +little more to say, sir, of his honesty: he has +every thing that an honest man should not have; what +an honest man should have, he has nothing. + + + +First Lord +I begin to love him for this. + + + +BERTRAM +For this description of thine honesty? A pox upon +him for me, he's more and more a cat. + + + +First Soldier +What say you to his expertness in war? + + + +PAROLLES +Faith, sir, he has led the drum before the English +tragedians; to belie him, I will not, and more of +his soldiership I know not; except, in that country +he had the honour to be the officer at a place there +called Mile-end, to instruct for the doubling of +files: I would do the man what honour I can, but of +this I am not certain. + + + +First Lord +He hath out-villained villany so far, that the +rarity redeems him. + + + +BERTRAM +A pox on him, he's a cat still. + + + +First Soldier +His qualities being at this poor price, I need not +to ask you if gold will corrupt him to revolt. + + + +PAROLLES +Sir, for a quart d'ecu he will sell the fee-simple +of his salvation, the inheritance of it; and cut the +entail from all remainders, and a perpetual +succession for it perpetually. + + + +First Soldier +What's his brother, the other Captain Dumain? + + + +Second Lord +Why does be ask him of me? + + + +First Soldier +What's he? + + + +PAROLLES +E'en a crow o' the same nest; not altogether so +great as the first in goodness, but greater a great +deal in evil: he excels his brother for a coward, +yet his brother is reputed one of the best that is: +in a retreat he outruns any lackey; marry, in coming +on he has the cramp. + + + +First Soldier +If your life be saved, will you undertake to betray +the Florentine? + + + +PAROLLES +Ay, and the captain of his horse, Count Rousillon. + + + +First Soldier +I'll whisper with the general, and know his pleasure. + + + +PAROLLES +Aside I'll no more drumming; a plague of all +drums! Only to seem to deserve well, and to +beguile the supposition of that lascivious young boy +the count, have I run into this danger. Yet who +would have suspected an ambush where I was taken? + + + +First Soldier +There is no remedy, sir, but you must die: the +general says, you that have so traitorously +discovered the secrets of your army and made such +pestiferous reports of men very nobly held, can +serve the world for no honest use; therefore you +must die. Come, headsman, off with his head. + + + +PAROLLES +O Lord, sir, let me live, or let me see my death! + + + +First Lord +That shall you, and take your leave of all your friends. +Unblinding him +So, look about you: know you any here? + + + +BERTRAM +Good morrow, noble captain. + + + +Second Lord +God bless you, Captain Parolles. + + + +First Lord +God save you, noble captain. + + + +Second Lord +Captain, what greeting will you to my Lord Lafeu? +I am for France. + + + +First Lord +Good captain, will you give me a copy of the sonnet +you writ to Diana in behalf of the Count Rousillon? +an I were not a very coward, I'ld compel it of you: +but fare you well. + + +Exeunt BERTRAM and Lords + + +First Soldier +You are undone, captain, all but your scarf; that +has a knot on't yet + + + +PAROLLES +Who cannot be crushed with a plot? + + + +First Soldier +If you could find out a country where but women were +that had received so much shame, you might begin an +impudent nation. Fare ye well, sir; I am for France +too: we shall speak of you there. + + +Exit with Soldiers + + +PAROLLES +Yet am I thankful: if my heart were great, +'Twould burst at this. Captain I'll be no more; +But I will eat and drink, and sleep as soft +As captain shall: simply the thing I am +Shall make me live. Who knows himself a braggart, +Let him fear this, for it will come to pass +that every braggart shall be found an ass. +Rust, sword? cool, blushes! and, Parolles, live +Safest in shame! being fool'd, by foolery thrive! +There's place and means for every man alive. +I'll after them. + + +Exit + + +SCENE IV. Florence. The Widow's house. +Enter HELENA, Widow, and DIANA + + +HELENA +That you may well perceive I have not wrong'd you, +One of the greatest in the Christian world +Shall be my surety; 'fore whose throne 'tis needful, +Ere I can perfect mine intents, to kneel: +Time was, I did him a desired office, +Dear almost as his life; which gratitude +Through flinty Tartar's bosom would peep forth, +And answer, thanks: I duly am inform'd +His grace is at Marseilles; to which place +We have convenient convoy. You must know +I am supposed dead: the army breaking, +My husband hies him home; where, heaven aiding, +And by the leave of my good lord the king, +We'll be before our welcome. + + + +Widow +Gentle madam, +You never had a servant to whose trust +Your business was more welcome. + + + +HELENA +Nor you, mistress, +Ever a friend whose thoughts more truly labour +To recompense your love: doubt not but heaven +Hath brought me up to be your daughter's dower, +As it hath fated her to be my motive +And helper to a husband. But, O strange men! +That can such sweet use make of what they hate, +When saucy trusting of the cozen'd thoughts +Defiles the pitchy night: so lust doth play +With what it loathes for that which is away. +But more of this hereafter. You, Diana, +Under my poor instructions yet must suffer +Something in my behalf. + + + +DIANA +Let death and honesty +Go with your impositions, I am yours +Upon your will to suffer. + + + +HELENA +Yet, I pray you: +But with the word the time will bring on summer, +When briers shall have leaves as well as thorns, +And be as sweet as sharp. We must away; +Our wagon is prepared, and time revives us: +All's well that ends well; still the fine's the crown; +Whate'er the course, the end is the renown. + + +Exeunt + + +SCENE V. Rousillon. The COUNT's palace. +Enter COUNTESS, LAFEU, and Clown + + +LAFEU +No, no, no, your son was misled with a snipt-taffeta +fellow there, whose villanous saffron would have +made all the unbaked and doughy youth of a nation in +his colour: your daughter-in-law had been alive at +this hour, and your son here at home, more advanced +by the king than by that red-tailed humble-bee I speak of. + + + +COUNTESS +I would I had not known him; it was the death of the +most virtuous gentlewoman that ever nature had +praise for creating. If she had partaken of my +flesh, and cost me the dearest groans of a mother, I +could not have owed her a more rooted love. + + + +LAFEU +'Twas a good lady, 'twas a good lady: we may pick a +thousand salads ere we light on such another herb. + + + +Clown +Indeed, sir, she was the sweet marjoram of the +salad, or rather, the herb of grace. + + + +LAFEU +They are not herbs, you knave; they are nose-herbs. + + + +Clown +I am no great Nebuchadnezzar, sir; I have not much +skill in grass. + + + +LAFEU +Whether dost thou profess thyself, a knave or a fool? + + + +Clown +A fool, sir, at a woman's service, and a knave at a man's. + + + +LAFEU +Your distinction? + + + +Clown +I would cozen the man of his wife and do his service. + + + +LAFEU +So you were a knave at his service, indeed. + + + +Clown +And I would give his wife my bauble, sir, to do her service. + + + +LAFEU +I will subscribe for thee, thou art both knave and fool. + + + +Clown +At your service. + + + +LAFEU +No, no, no. + + + +Clown +Why, sir, if I cannot serve you, I can serve as +great a prince as you are. + + + +LAFEU +Who's that? a Frenchman? + + + +Clown +Faith, sir, a' has an English name; but his fisnomy +is more hotter in France than there. + + + +LAFEU +What prince is that? + + + +Clown +The black prince, sir; alias, the prince of +darkness; alias, the devil. + + + +LAFEU +Hold thee, there's my purse: I give thee not this +to suggest thee from thy master thou talkest of; +serve him still. + + + +Clown +I am a woodland fellow, sir, that always loved a +great fire; and the master I speak of ever keeps a +good fire. But, sure, he is the prince of the +world; let his nobility remain in's court. I am for +the house with the narrow gate, which I take to be +too little for pomp to enter: some that humble +themselves may; but the many will be too chill and +tender, and they'll be for the flowery way that +leads to the broad gate and the great fire. + + + +LAFEU +Go thy ways, I begin to be aweary of thee; and I +tell thee so before, because I would not fall out +with thee. Go thy ways: let my horses be well +looked to, without any tricks. + + + +Clown +If I put any tricks upon 'em, sir, they shall be +jades' tricks; which are their own right by the law of nature. + + +Exit + + +LAFEU +A shrewd knave and an unhappy. + + + +COUNTESS +So he is. My lord that's gone made himself much +sport out of him: by his authority he remains here, +which he thinks is a patent for his sauciness; and, +indeed, he has no pace, but runs where he will. + + + +LAFEU +I like him well; 'tis not amiss. And I was about to +tell you, since I heard of the good lady's death and +that my lord your son was upon his return home, I +moved the king my master to speak in the behalf of +my daughter; which, in the minority of them both, +his majesty, out of a self-gracious remembrance, did +first propose: his highness hath promised me to do +it: and, to stop up the displeasure he hath +conceived against your son, there is no fitter +matter. How does your ladyship like it? + + + +COUNTESS +With very much content, my lord; and I wish it +happily effected. + + + +LAFEU +His highness comes post from Marseilles, of as able +body as when he numbered thirty: he will be here +to-morrow, or I am deceived by him that in such +intelligence hath seldom failed. + + + +COUNTESS +It rejoices me, that I hope I shall see him ere I +die. I have letters that my son will be here +to-night: I shall beseech your lordship to remain +with me till they meet together. + + + +LAFEU +Madam, I was thinking with what manners I might +safely be admitted. + + + +COUNTESS +You need but plead your honourable privilege. + + + +LAFEU +Lady, of that I have made a bold charter; but I +thank my God it holds yet. + + +Re-enter Clown + + +Clown +O madam, yonder's my lord your son with a patch of +velvet on's face: whether there be a scar under't +or no, the velvet knows; but 'tis a goodly patch of +velvet: his left cheek is a cheek of two pile and a +half, but his right cheek is worn bare. + + + +LAFEU +A scar nobly got, or a noble scar, is a good livery +of honour; so belike is that. + + + +Clown +But it is your carbonadoed face. + + + +LAFEU +Let us go see your son, I pray you: I long to talk +with the young noble soldier. + + + +Clown +Faith there's a dozen of 'em, with delicate fine +hats and most courteous feathers, which bow the head +and nod at every man. + + +Exeunt + + + + +ACT V + +SCENE I. Marseilles. A street. +Enter HELENA, Widow, and DIANA, with two +Attendants + + +HELENA +But this exceeding posting day and night +Must wear your spirits low; we cannot help it: +But since you have made the days and nights as one, +To wear your gentle limbs in my affairs, +Be bold you do so grow in my requital +As nothing can unroot you. In happy time; +Enter a Gentleman +This man may help me to his majesty's ear, +If he would spend his power. God save you, sir. + + + +Gentleman +And you. + + + +HELENA +Sir, I have seen you in the court of France. + + + +Gentleman +I have been sometimes there. + + + +HELENA +I do presume, sir, that you are not fallen +From the report that goes upon your goodness; +An therefore, goaded with most sharp occasions, +Which lay nice manners by, I put you to +The use of your own virtues, for the which +I shall continue thankful. + + + +Gentleman +What's your will? + + + +HELENA +That it will please you +To give this poor petition to the king, +And aid me with that store of power you have +To come into his presence. + + + +Gentleman +The king's not here. + + + +HELENA +Not here, sir! + + + +Gentleman +Not, indeed: +He hence removed last night and with more haste +Than is his use. + + + +Widow +Lord, how we lose our pains! + + + +HELENA +All's well that ends well yet, +Though time seem so adverse and means unfit. +I do beseech you, whither is he gone? + + + +Gentleman +Marry, as I take it, to Rousillon; +Whither I am going. + + + +HELENA +I do beseech you, sir, +Since you are like to see the king before me, +Commend the paper to his gracious hand, +Which I presume shall render you no blame +But rather make you thank your pains for it. +I will come after you with what good speed +Our means will make us means. + + + +Gentleman +This I'll do for you. + + + +HELENA +And you shall find yourself to be well thank'd, +Whate'er falls more. We must to horse again. +Go, go, provide. + + +Exeunt + + +SCENE II. Rousillon. Before the COUNT's palace. +Enter Clown, and PAROLLES, following + + +PAROLLES +Good Monsieur Lavache, give my Lord Lafeu this +letter: I have ere now, sir, been better known to +you, when I have held familiarity with fresher +clothes; but I am now, sir, muddied in fortune's +mood, and smell somewhat strong of her strong +displeasure. + + + +Clown +Truly, fortune's displeasure is but sluttish, if it +smell so strongly as thou speakest of: I will +henceforth eat no fish of fortune's buttering. +Prithee, allow the wind. + + + +PAROLLES +Nay, you need not to stop your nose, sir; I spake +but by a metaphor. + + + +Clown +Indeed, sir, if your metaphor stink, I will stop my +nose; or against any man's metaphor. Prithee, get +thee further. + + + +PAROLLES +Pray you, sir, deliver me this paper. + + + +Clown +Foh! prithee, stand away: a paper from fortune's +close-stool to give to a nobleman! Look, here he +comes himself. +Enter LAFEU +Here is a purr of fortune's, sir, or of fortune's +cat,--but not a musk-cat,--that has fallen into the +unclean fishpond of her displeasure, and, as he +says, is muddied withal: pray you, sir, use the +carp as you may; for he looks like a poor, decayed, +ingenious, foolish, rascally knave. I do pity his +distress in my similes of comfort and leave him to +your lordship. + + +Exit + + +PAROLLES +My lord, I am a man whom fortune hath cruelly +scratched. + + + +LAFEU +And what would you have me to do? 'Tis too late to +pare her nails now. Wherein have you played the +knave with fortune, that she should scratch you, who +of herself is a good lady and would not have knaves +thrive long under her? There's a quart d'ecu for +you: let the justices make you and fortune friends: +I am for other business. + + + +PAROLLES +I beseech your honour to hear me one single word. + + + +LAFEU +You beg a single penny more: come, you shall ha't; +save your word. + + + +PAROLLES +My name, my good lord, is Parolles. + + + +LAFEU +You beg more than 'word,' then. Cox my passion! +give me your hand. How does your drum? + + + +PAROLLES +O my good lord, you were the first that found me! + + + +LAFEU +Was I, in sooth? and I was the first that lost thee. + + + +PAROLLES +It lies in you, my lord, to bring me in some grace, +for you did bring me out. + + + +LAFEU +Out upon thee, knave! dost thou put upon me at once +both the office of God and the devil? One brings +thee in grace and the other brings thee out. +Trumpets sound +The king's coming; I know by his trumpets. Sirrah, +inquire further after me; I had talk of you last +night: though you are a fool and a knave, you shall +eat; go to, follow. + + + +PAROLLES +I praise God for you. + + +Exeunt + + +SCENE III. Rousillon. The COUNT's palace. +Flourish. Enter KING, COUNTESS, LAFEU, the two +French Lords, with Attendants + + +KING +We lost a jewel of her; and our esteem +Was made much poorer by it: but your son, +As mad in folly, lack'd the sense to know +Her estimation home. + + + +COUNTESS +'Tis past, my liege; +And I beseech your majesty to make it +Natural rebellion, done i' the blaze of youth; +When oil and fire, too strong for reason's force, +O'erbears it and burns on. + + + +KING +My honour'd lady, +I have forgiven and forgotten all; +Though my revenges were high bent upon him, +And watch'd the time to shoot. + + + +LAFEU +This I must say, +But first I beg my pardon, the young lord +Did to his majesty, his mother and his lady +Offence of mighty note; but to himself +The greatest wrong of all. He lost a wife +Whose beauty did astonish the survey +Of richest eyes, whose words all ears took captive, +Whose dear perfection hearts that scorn'd to serve +Humbly call'd mistress. + + + +KING +Praising what is lost +Makes the remembrance dear. Well, call him hither; +We are reconciled, and the first view shall kill +All repetition: let him not ask our pardon; +The nature of his great offence is dead, +And deeper than oblivion we do bury +The incensing relics of it: let him approach, +A stranger, no offender; and inform him +So 'tis our will he should. + + + +Gentleman +I shall, my liege. + + +Exit + + +KING +What says he to your daughter? have you spoke? + + + +LAFEU +All that he is hath reference to your highness. + + + +KING +Then shall we have a match. I have letters sent me +That set him high in fame. + + +Enter BERTRAM + + +LAFEU +He looks well on't. + + + +KING +I am not a day of season, +For thou mayst see a sunshine and a hail +In me at once: but to the brightest beams +Distracted clouds give way; so stand thou forth; +The time is fair again. + + + +BERTRAM +My high-repented blames, +Dear sovereign, pardon to me. + + + +KING +All is whole; +Not one word more of the consumed time. +Let's take the instant by the forward top; +For we are old, and on our quick'st decrees +The inaudible and noiseless foot of Time +Steals ere we can effect them. You remember +The daughter of this lord? + + + +BERTRAM +Admiringly, my liege, at first +I stuck my choice upon her, ere my heart +Durst make too bold a herald of my tongue +Where the impression of mine eye infixing, +Contempt his scornful perspective did lend me, +Which warp'd the line of every other favour; +Scorn'd a fair colour, or express'd it stolen; +Extended or contracted all proportions +To a most hideous object: thence it came +That she whom all men praised and whom myself, +Since I have lost, have loved, was in mine eye +The dust that did offend it. + + + +KING +Well excused: +That thou didst love her, strikes some scores away +From the great compt: but love that comes too late, +Like a remorseful pardon slowly carried, +To the great sender turns a sour offence, +Crying, 'That's good that's gone.' Our rash faults +Make trivial price of serious things we have, +Not knowing them until we know their grave: +Oft our displeasures, to ourselves unjust, +Destroy our friends and after weep their dust +Our own love waking cries to see what's done, +While shame full late sleeps out the afternoon. +Be this sweet Helen's knell, and now forget her. +Send forth your amorous token for fair Maudlin: +The main consents are had; and here we'll stay +To see our widower's second marriage-day. + + + +COUNTESS +Which better than the first, O dear heaven, bless! +Or, ere they meet, in me, O nature, cesse! + + + +LAFEU +Come on, my son, in whom my house's name +Must be digested, give a favour from you +To sparkle in the spirits of my daughter, +That she may quickly come. +BERTRAM gives a ring +By my old beard, +And every hair that's on't, Helen, that's dead, +Was a sweet creature: such a ring as this, +The last that e'er I took her at court, +I saw upon her finger. + + + +BERTRAM +Hers it was not. + + + +KING +Now, pray you, let me see it; for mine eye, +While I was speaking, oft was fasten'd to't. +This ring was mine; and, when I gave it Helen, +I bade her, if her fortunes ever stood +Necessitied to help, that by this token +I would relieve her. Had you that craft, to reave +her +Of what should stead her most? + + + +BERTRAM +My gracious sovereign, +Howe'er it pleases you to take it so, +The ring was never hers. + + + +COUNTESS +Son, on my life, +I have seen her wear it; and she reckon'd it +At her life's rate. + + + +LAFEU +I am sure I saw her wear it. + + + +BERTRAM +You are deceived, my lord; she never saw it: +In Florence was it from a casement thrown me, +Wrapp'd in a paper, which contain'd the name +Of her that threw it: noble she was, and thought +I stood engaged: but when I had subscribed +To mine own fortune and inform'd her fully +I could not answer in that course of honour +As she had made the overture, she ceased +In heavy satisfaction and would never +Receive the ring again. + + + +KING +Plutus himself, +That knows the tinct and multiplying medicine, +Hath not in nature's mystery more science +Than I have in this ring: 'twas mine, 'twas Helen's, +Whoever gave it you. Then, if you know +That you are well acquainted with yourself, +Confess 'twas hers, and by what rough enforcement +You got it from her: she call'd the saints to surety +That she would never put it from her finger, +Unless she gave it to yourself in bed, +Where you have never come, or sent it us +Upon her great disaster. + + + +BERTRAM +She never saw it. + + + +KING +Thou speak'st it falsely, as I love mine honour; +And makest conjectural fears to come into me +Which I would fain shut out. If it should prove +That thou art so inhuman,--'twill not prove so;-- +And yet I know not: thou didst hate her deadly, +And she is dead; which nothing, but to close +Her eyes myself, could win me to believe, +More than to see this ring. Take him away. +Guards seize BERTRAM +My fore-past proofs, howe'er the matter fall, +Shall tax my fears of little vanity, +Having vainly fear'd too little. Away with him! +We'll sift this matter further. + + + +BERTRAM +If you shall prove +This ring was ever hers, you shall as easy +Prove that I husbanded her bed in Florence, +Where yet she never was. + + +Exit, guarded + + +KING +I am wrapp'd in dismal thinkings. + + +Enter a Gentleman + + +Gentleman +Gracious sovereign, +Whether I have been to blame or no, I know not: +Here's a petition from a Florentine, +Who hath for four or five removes come short +To tender it herself. I undertook it, +Vanquish'd thereto by the fair grace and speech +Of the poor suppliant, who by this I know +Is here attending: her business looks in her +With an importing visage; and she told me, +In a sweet verbal brief, it did concern +Your highness with herself. + + + +KING +Reads Upon his many protestations to marry me +when his wife was dead, I blush to say it, he won +me. Now is the Count Rousillon a widower: his vows +are forfeited to me, and my honour's paid to him. He +stole from Florence, taking no leave, and I follow +him to his country for justice: grant it me, O +king! in you it best lies; otherwise a seducer +flourishes, and a poor maid is undone. +DIANA CAPILET. + + + +LAFEU +I will buy me a son-in-law in a fair, and toll for +this: I'll none of him. + + + +KING +The heavens have thought well on thee Lafeu, +To bring forth this discovery. Seek these suitors: +Go speedily and bring again the count. +I am afeard the life of Helen, lady, +Was foully snatch'd. + + + +COUNTESS +Now, justice on the doers! + + +Re-enter BERTRAM, guarded + + +KING +I wonder, sir, sith wives are monsters to you, +And that you fly them as you swear them lordship, +Yet you desire to marry. +Enter Widow and DIANA +What woman's that? + + + +DIANA +I am, my lord, a wretched Florentine, +Derived from the ancient Capilet: +My suit, as I do understand, you know, +And therefore know how far I may be pitied. + + + +Widow +I am her mother, sir, whose age and honour +Both suffer under this complaint we bring, +And both shall cease, without your remedy. + + + +KING +Come hither, count; do you know these women? + + + +BERTRAM +My lord, I neither can nor will deny +But that I know them: do they charge me further? + + + +DIANA +Why do you look so strange upon your wife? + + + +BERTRAM +She's none of mine, my lord. + + + +DIANA +If you shall marry, +You give away this hand, and that is mine; +You give away heaven's vows, and those are mine; +You give away myself, which is known mine; +For I by vow am so embodied yours, +That she which marries you must marry me, +Either both or none. + + + +LAFEU +Your reputation comes too short for my daughter; you +are no husband for her. + + + +BERTRAM +My lord, this is a fond and desperate creature, +Whom sometime I have laugh'd with: let your highness +Lay a more noble thought upon mine honour +Than for to think that I would sink it here. + + + +KING +Sir, for my thoughts, you have them ill to friend +Till your deeds gain them: fairer prove your honour +Than in my thought it lies. + + + +DIANA +Good my lord, +Ask him upon his oath, if he does think +He had not my virginity. + + + +KING +What say'st thou to her? + + + +BERTRAM +She's impudent, my lord, +And was a common gamester to the camp. + + + +DIANA +He does me wrong, my lord; if I were so, +He might have bought me at a common price: +Do not believe him. O, behold this ring, +Whose high respect and rich validity +Did lack a parallel; yet for all that +He gave it to a commoner o' the camp, +If I be one. + + + +COUNTESS +He blushes, and 'tis it: +Of six preceding ancestors, that gem, +Conferr'd by testament to the sequent issue, +Hath it been owed and worn. This is his wife; +That ring's a thousand proofs. + + + +KING +Methought you said +You saw one here in court could witness it. + + + +DIANA +I did, my lord, but loath am to produce +So bad an instrument: his name's Parolles. + + + +LAFEU +I saw the man to-day, if man he be. + + + +KING +Find him, and bring him hither. + + +Exit an Attendant + + +BERTRAM +What of him? +He's quoted for a most perfidious slave, +With all the spots o' the world tax'd and debosh'd; +Whose nature sickens but to speak a truth. +Am I or that or this for what he'll utter, +That will speak any thing? + + + +KING +She hath that ring of yours. + + + +BERTRAM +I think she has: certain it is I liked her, +And boarded her i' the wanton way of youth: +She knew her distance and did angle for me, +Madding my eagerness with her restraint, +As all impediments in fancy's course +Are motives of more fancy; and, in fine, +Her infinite cunning, with her modern grace, +Subdued me to her rate: she got the ring; +And I had that which any inferior might +At market-price have bought. + + + +DIANA +I must be patient: +You, that have turn'd off a first so noble wife, +May justly diet me. I pray you yet; +Since you lack virtue, I will lose a husband; +Send for your ring, I will return it home, +And give me mine again. + + + +BERTRAM +I have it not. + + + +KING +What ring was yours, I pray you? + + + +DIANA +Sir, much like +The same upon your finger. + + + +KING +Know you this ring? this ring was his of late. + + + +DIANA +And this was it I gave him, being abed. + + + +KING +The story then goes false, you threw it him +Out of a casement. + + + +DIANA +I have spoke the truth. + + +Enter PAROLLES + + +BERTRAM +My lord, I do confess the ring was hers. + + + +KING +You boggle shrewdly, every feather stars you. +Is this the man you speak of? + + + +DIANA +Ay, my lord. + + + +KING +Tell me, sirrah, but tell me true, I charge you, +Not fearing the displeasure of your master, +Which on your just proceeding I'll keep off, +By him and by this woman here what know you? + + + +PAROLLES +So please your majesty, my master hath been an +honourable gentleman: tricks he hath had in him, +which gentlemen have. + + + +KING +Come, come, to the purpose: did he love this woman? + + + +PAROLLES +Faith, sir, he did love her; but how? + + + +KING +How, I pray you? + + + +PAROLLES +He did love her, sir, as a gentleman loves a woman. + + + +KING +How is that? + + + +PAROLLES +He loved her, sir, and loved her not. + + + +KING +As thou art a knave, and no knave. What an +equivocal companion is this! + + + +PAROLLES +I am a poor man, and at your majesty's command. + + + +LAFEU +He's a good drum, my lord, but a naughty orator. + + + +DIANA +Do you know he promised me marriage? + + + +PAROLLES +Faith, I know more than I'll speak. + + + +KING +But wilt thou not speak all thou knowest? + + + +PAROLLES +Yes, so please your majesty. I did go between them, +as I said; but more than that, he loved her: for +indeed he was mad for her, and talked of Satan and +of Limbo and of Furies and I know not what: yet I +was in that credit with them at that time that I +knew of their going to bed, and of other motions, +as promising her marriage, and things which would +derive me ill will to speak of; therefore I will not +speak what I know. + + + +KING +Thou hast spoken all already, unless thou canst say +they are married: but thou art too fine in thy +evidence; therefore stand aside. +This ring, you say, was yours? + + + +DIANA +Ay, my good lord. + + + +KING +Where did you buy it? or who gave it you? + + + +DIANA +It was not given me, nor I did not buy it. + + + +KING +Who lent it you? + + + +DIANA +It was not lent me neither. + + + +KING +Where did you find it, then? + + + +DIANA +I found it not. + + + +KING +If it were yours by none of all these ways, +How could you give it him? + + + +DIANA +I never gave it him. + + + +LAFEU +This woman's an easy glove, my lord; she goes off +and on at pleasure. + + + +KING +This ring was mine; I gave it his first wife. + + + +DIANA +It might be yours or hers, for aught I know. + + + +KING +Take her away; I do not like her now; +To prison with her: and away with him. +Unless thou tell'st me where thou hadst this ring, +Thou diest within this hour. + + + +DIANA +I'll never tell you. + + + +KING +Take her away. + + + +DIANA +I'll put in bail, my liege. + + + +KING +I think thee now some common customer. + + + +DIANA +By Jove, if ever I knew man, 'twas you. + + + +KING +Wherefore hast thou accused him all this while? + + + +DIANA +Because he's guilty, and he is not guilty: +He knows I am no maid, and he'll swear to't; +I'll swear I am a maid, and he knows not. +Great king, I am no strumpet, by my life; +I am either maid, or else this old man's wife. + + + +KING +She does abuse our ears: to prison with her. + + + +DIANA +Good mother, fetch my bail. Stay, royal sir: +Exit Widow +The jeweller that owes the ring is sent for, +And he shall surety me. But for this lord, +Who hath abused me, as he knows himself, +Though yet he never harm'd me, here I quit him: +He knows himself my bed he hath defiled; +And at that time he got his wife with child: +Dead though she be, she feels her young one kick: +So there's my riddle: one that's dead is quick: +And now behold the meaning. + + +Re-enter Widow, with HELENA + + +KING +Is there no exorcist +Beguiles the truer office of mine eyes? +Is't real that I see? + + + +HELENA +No, my good lord; +'Tis but the shadow of a wife you see, +The name and not the thing. + + + +BERTRAM +Both, both. O, pardon! + + + +HELENA +O my good lord, when I was like this maid, +I found you wondrous kind. There is your ring; +And, look you, here's your letter; this it says: +'When from my finger you can get this ring +And are by me with child,' &c. This is done: +Will you be mine, now you are doubly won? + + + +BERTRAM +If she, my liege, can make me know this clearly, +I'll love her dearly, ever, ever dearly. + + + +HELENA +If it appear not plain and prove untrue, +Deadly divorce step between me and you! +O my dear mother, do I see you living? + + + +LAFEU +Mine eyes smell onions; I shall weep anon: +To PAROLLES +Good Tom Drum, lend me a handkercher: so, +I thank thee: wait on me home, I'll make sport with thee: +Let thy courtesies alone, they are scurvy ones. + + + +KING +Let us from point to point this story know, +To make the even truth in pleasure flow. +To DIANA +If thou be'st yet a fresh uncropped flower, +Choose thou thy husband, and I'll pay thy dower; +For I can guess that by thy honest aid +Thou keep'st a wife herself, thyself a maid. +Of that and all the progress, more or less, +Resolvedly more leisure shall express: +All yet seems well; and if it end so meet, +The bitter past, more welcome is the sweet. + +Flourish + + +EPILOGUE + +KING +The king's a beggar, now the play is done: +All is well ended, if this suit be won, +That you express content; which we will pay, +With strife to please you, day exceeding day: +Ours be your patience then, and yours our parts; +Your gentle hands lend us, and take our hearts. + + +Exeunt + + +
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bbq1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq1.xml new file mode 100644 index 000000000..b43c4339d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq1.xml @@ -0,0 +1,9 @@ + + Sally's Southern BBQ + A classic southern recipe + cayanne + molasses + smoky + 800 + 3.0 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bbq2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq2.xml new file mode 100644 index 000000000..e7ce18386 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq2.xml @@ -0,0 +1,9 @@ + + Red, Hot, and Blue + Texas-style sauce with extra heat + habenero + black pepper + smoky + 72000 + 4.0 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bbq3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq3.xml new file mode 100644 index 000000000..f490363d3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq3.xml @@ -0,0 +1,8 @@ + + Louisiana Bayou Mild + Straight from New Orleans, mild and sweet + sweet + vinegar + 750 + 5.0 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bbq4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq4.xml new file mode 100644 index 000000000..e9498d278 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq4.xml @@ -0,0 +1,10 @@ + + Four little pigs + Southern Texas-style sauce with extreme heat + habenero + black pepper + smoky + brown sugar + 88000 + 5.0 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bbq5.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq5.xml new file mode 100644 index 000000000..3d00d04f6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bbq5.xml @@ -0,0 +1,9 @@ + + Kansas City Apple Cinnamon + Specialty recipe made with real fruit and spices + apple + cinnamon + brown sugar + 1000 + 2.0 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/binary.jpg b/test-complete/src/test/java/com/marklogic/javaclient/data/binary.jpg new file mode 100644 index 000000000..61348a17f Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/binary.jpg differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/book.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/book.xml new file mode 100644 index 000000000..36104b7d7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/book.xml @@ -0,0 +1,17 @@ + + + Kiran + Pai + 22 + + + Bill + Gates + 46 + + + Steve + Jobs + 40 + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bug19016.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bug19016.xml new file mode 100644 index 000000000..22f919362 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bug19016.xml @@ -0,0 +1,3 @@ + + this"is"an%33odd string + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/bug21183.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/bug21183.xml new file mode 100644 index 000000000..b29030419 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/bug21183.xml @@ -0,0 +1,4 @@ + + +a + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal1.xml new file mode 100644 index 000000000..c23b11470 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal1.xml @@ -0,0 +1,7 @@ + + one + two + three + four + five + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal2.xml new file mode 100644 index 000000000..21d89cc41 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal2.xml @@ -0,0 +1,3 @@ + + one + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal3.xml new file mode 100644 index 000000000..6ea2981be --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal3.xml @@ -0,0 +1,3 @@ + + one + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal4.xml new file mode 100644 index 000000000..c23b11470 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/cardinal4.xml @@ -0,0 +1,7 @@ + + one + two + three + four + five + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.json b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.json new file mode 100644 index 000000000..fe13b2a32 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.json @@ -0,0 +1 @@ +{"root":{"title":"Vannevar Bush", "popularity":"5", "id":"0011", "date":"2005-01-01", "price":{"amt":"0.1"}, "p":"Vannevar Bush wrote an article for The Atlantic Monthly"}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.xml new file mode 100644 index 000000000..6171ef4db --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint1.xml @@ -0,0 +1,8 @@ + + Vannevar Bush + 5 + 0011 + 2005-01-01 + +

Vannevar Bush wrote an article for The Atlantic Monthly

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.json b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.json new file mode 100644 index 000000000..89065d0e3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.json @@ -0,0 +1 @@ +{"root":{"title":"The Bush article", "popularity":"4", "id":"0012", "date":"2006-02-02", "price":{"amt":"0.12"}, "p":"The Bush article described a device called a Memex."}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.xml new file mode 100644 index 000000000..4fb6046c4 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint2.xml @@ -0,0 +1,8 @@ + + The Bush article + 4 + 0012 + 2006-02-02 + +

The Bush article described a device called a Memex.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.json b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.json new file mode 100644 index 000000000..dc594b7ba --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.json @@ -0,0 +1 @@ +{"root":{"title":"For 1945", "popularity":"3", "id":"0113", "date":"2007-03-03", "price":{"amt":"1.23"}, "p":"For 1945, the thoughts expressed in The Atlantic Monthly were groundbreaking."}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.xml new file mode 100644 index 000000000..8bb321854 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint3.xml @@ -0,0 +1,8 @@ + + For 1945 + 3 + 0113 + 2007-03-03 + +

For 1945, the thoughts expressed in The Atlantic Monthly were groundbreaking.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.json b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.json new file mode 100644 index 000000000..75e462e77 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.json @@ -0,0 +1 @@ +{"root":{"title":"Vannevar served", "popularity":"5", "id":"0024", "date":"2008-04-04", "price":{"amt":"12.34"}, "p":"Vannevar served as a prominent policymaker and public intellectual."}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.xml new file mode 100644 index 000000000..1e84506ce --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint4.xml @@ -0,0 +1,8 @@ + + Vannevar served + 5 + 0024 + 2008-04-04 + +

Vannevar served as a prominent policymaker and public intellectual.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.json b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.json new file mode 100644 index 000000000..5ebb4d2ae --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.json @@ -0,0 +1 @@ +{"root":{"title":"The memex", "popularity":"5", "id":"0026", "date":"2009-05-05", "price":{"amt":"123.45"}, "p":"The Memex, unfortunately, had no automated search feature."}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.xml new file mode 100644 index 000000000..4dea1638f --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint5.xml @@ -0,0 +1,8 @@ + + The memex + 5 + 0026 + 2009-05-05 + +

The Memex, unfortunately, had no automated search feature.

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/constraint6.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint6.xml new file mode 100644 index 000000000..145821024 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/constraint6.xml @@ -0,0 +1,15 @@ + + 5 + 5 + 2 + 20 + Hi + Version + 7 + ML Version 7 + ML Version 7 + Client + API + Tests + Mayank + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/curbappeal.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/curbappeal.xml new file mode 100644 index 000000000..33d5aec7d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/curbappeal.xml @@ -0,0 +1,8 @@ + + + Curb Appeal + Real Estate + Provides heatmap of income demographics for selected neighborhoods. + Includes leaderboard for weekly orders on remodel materials including color schemes. + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/custom-lib.xqy b/test-complete/src/test/java/com/marklogic/javaclient/data/custom-lib.xqy new file mode 100644 index 000000000..43ea9ff5d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/custom-lib.xqy @@ -0,0 +1,25 @@ +xquery version "1.0-ml"; + +module namespace custom-lib = + "http://marklogic.com/ext/patch/custom-lib"; + +declare function custom-lib:underwrite( + $node as node()?, + $content as item()* +) as node()* +{ + let $element := $content[1] + return + if (empty($node)) + then $element + else + let $atts := $element/@* + let $att-names := $atts/node-name(.) + return element {node-name($node)} { + $node/@*[not(node-name(.) = $att-names)], + $atts, + $node/node(), + $element/node() + } + +}; \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/element-attribute-pair-geo-data.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/element-attribute-pair-geo-data.xml new file mode 100644 index 000000000..f0739d1cb --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/element-attribute-pair-geo-data.xml @@ -0,0 +1,38 @@ + + + beijing + city in china + + + bangkok + city in thailand + + + norh pole + place where Santa lives + + + south pole + place where Bad Santa lives + + + Unalaska Island + Part of the Aleutian Islands. Near Alaska + + + Quito + Capital of Ecuador. Near the equator. + + + Funafuti + Capital of island nation of Tuvalu. + + + Berlin + City in Germany + +

How is the weather in Quito

+

How is the weather in Quito today or tomorrow . I need vacation.

+

How is the weather in North Pole

+

How is the weather in the North Pole today or tomorrow . I need vacation.

+
diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/employee-stylesheet.xsl b/test-complete/src/test/java/com/marklogic/javaclient/data/employee-stylesheet.xsl new file mode 100644 index 000000000..d07e300c1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/employee-stylesheet.xsl @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/employee.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/employee.xml new file mode 100644 index 000000000..c0072b831 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/employee.xml @@ -0,0 +1,12 @@ + + + + John + + + Jane + + + Bob + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/facebook-10443244874876159931 b/test-complete/src/test/java/com/marklogic/javaclient/data/facebook-10443244874876159931 new file mode 100644 index 000000000..abaa0cdcf --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/facebook-10443244874876159931 @@ -0,0 +1,2 @@ + +10443244874876159931100000666747305_1548332712652692011-08-22T18:48:352011-08-22T16:00:09.170777-04:002011-08-22T18:48:35facebook100000666747305NIcholas Smith1225097529214212557 \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/flipper.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/flipper.xml new file mode 100644 index 000000000..774db4c2e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/flipper.xml @@ -0,0 +1,9 @@ + + + Flipper + Real Estate + Discovers correlations and trending criteria. + Finds neighborhoods matching specified criteria. + Sends alert when a property qualifies for criteria. + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint1.xml new file mode 100644 index 000000000..504d4d30b --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint1.xml @@ -0,0 +1,12 @@ + + karl_kara + 12,5 + + 12,5 + + + 12 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint10.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint10.xml new file mode 100644 index 000000000..d9c89f4b5 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint10.xml @@ -0,0 +1,13 @@ + + + bill_kara + -13,-5 + + -13,-5 + + + -13 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint11.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint11.xml new file mode 100644 index 000000000..bad13c7be --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint11.xml @@ -0,0 +1,13 @@ + + + jack_kara + -11,-5 + + -11,-5 + + + -11 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint12.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint12.xml new file mode 100644 index 000000000..66ec651ed --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint12.xml @@ -0,0 +1,13 @@ + + + karl_gale + -12,-6 + + -12,-6 + + + -12 + -6 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint13.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint13.xml new file mode 100644 index 000000000..9d19503c3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint13.xml @@ -0,0 +1,13 @@ + + + karl_jill + -12,-4 + + -12,-4 + + + -12 + -4 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint14.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint14.xml new file mode 100644 index 000000000..7c53f85cf --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint14.xml @@ -0,0 +1,13 @@ + + + jack_jill + -11,-4 + + -11,-4 + + + -11 + -4 + + + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint15.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint15.xml new file mode 100644 index 000000000..c03c5e94c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint15.xml @@ -0,0 +1,12 @@ + + karl_kara + 12,-5 + + 12,-5 + + + 12 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint16.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint16.xml new file mode 100644 index 000000000..bcc4c1216 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint16.xml @@ -0,0 +1,13 @@ + + + bill_kara + 13,-5 + + 13,-5 + + + 13 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint17.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint17.xml new file mode 100644 index 000000000..fff8154a6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint17.xml @@ -0,0 +1,13 @@ + + + jack_kara + 11,-5 + + 11,-5 + + + 11 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint18.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint18.xml new file mode 100644 index 000000000..e1e0afd8a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint18.xml @@ -0,0 +1,13 @@ + + + karl_gale + 12,-6 + + 12,-6 + + + 12 + -6 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint19.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint19.xml new file mode 100644 index 000000000..a658f51f9 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint19.xml @@ -0,0 +1,13 @@ + + + karl_jill + 12,-4 + + 12,-4 + + + 12 + -4 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint2.xml new file mode 100644 index 000000000..e54064dd0 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint2.xml @@ -0,0 +1,13 @@ + + + karl_kara + -12,-5 + + -12,-5 + + + -12 + -5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint20.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint20.xml new file mode 100644 index 000000000..c2f08e926 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint20.xml @@ -0,0 +1,12 @@ + + karl_kara + -12,5 + + -12,5 + + + -12 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint21.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint21.xml new file mode 100644 index 000000000..0f7725ce9 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint21.xml @@ -0,0 +1,13 @@ + + + bill_kara + -13,5 + + -13,5 + + + -13 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint22.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint22.xml new file mode 100644 index 000000000..3fac27137 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint22.xml @@ -0,0 +1,13 @@ + + + jack_kara + -11,5 + + -11,5 + + + -11 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint23.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint23.xml new file mode 100644 index 000000000..6da58c1ec --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint23.xml @@ -0,0 +1,13 @@ + + + karl_gale + -12,6 + + -12,6 + + + -12 + 6 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint24.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint24.xml new file mode 100644 index 000000000..ff665eeb9 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint24.xml @@ -0,0 +1,13 @@ + + + karl_jill + -12,4 + + -12,4 + + + -12 + 4 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint3.xml new file mode 100644 index 000000000..947fce6d3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint3.xml @@ -0,0 +1,13 @@ + + + bill_kara + 13,5 + + 13,5 + + + 13 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint4.xml new file mode 100644 index 000000000..697589e04 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint4.xml @@ -0,0 +1,13 @@ + + + jack_kara + 11,5 + + 11,5 + + + 11 + 5 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint5.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint5.xml new file mode 100644 index 000000000..d3e191a71 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint5.xml @@ -0,0 +1,13 @@ + + + karl_gale + 12,6 + + 12,6 + + + 12 + 6 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint6.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint6.xml new file mode 100644 index 000000000..2e3d8024d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint6.xml @@ -0,0 +1,13 @@ + + + karl_jill + 12,4 + + 12,4 + + + 12 + 4 + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint7.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint7.xml new file mode 100644 index 000000000..f384e3858 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint7.xml @@ -0,0 +1,13 @@ + + + jack_jill + 11,4 + + 11,4 + + + 11 + 4 + + + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint8.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint8.xml new file mode 100644 index 000000000..0fa8b6612 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint8.xml @@ -0,0 +1,13 @@ + + + john_andrew + 150,-140 + + 150,-140 + + + 150 + -140 + + + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint9.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint9.xml new file mode 100644 index 000000000..f7f67ead7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/geo-constraint9.xml @@ -0,0 +1,13 @@ + + + jane_smith + 150,-140 + + 150,-140 + + + 150 + -140 + + + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/json-original.json b/test-complete/src/test/java/com/marklogic/javaclient/data/json-original.json new file mode 100644 index 000000000..caea3e8d4 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/json-original.json @@ -0,0 +1,7 @@ +{ +"employees": [ +{ "firstName":"John" , "lastName":"Doe" }, +{ "firstName":"Ann" , "lastName":"Smith" }, +{ "firstName":"Bob" , "lastName":"Foo" } +] +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/json-updated.json b/test-complete/src/test/java/com/marklogic/javaclient/data/json-updated.json new file mode 100644 index 000000000..6651529c7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/json-updated.json @@ -0,0 +1,6 @@ +{ +"employees": [ +{ "firstName":"Aries" , "lastName":"Yuwono" }, +{ "firstName":"Bob" , "lastName":"Foo" } +] +} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/justintime.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/justintime.xml new file mode 100644 index 000000000..23fbd7e1d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/justintime.xml @@ -0,0 +1,9 @@ + + + Just-In-Time + Retail + Represents inventory at point-of-sale as a heatmap. + Automates brokering of transfers and shipments to maintain inventory + at specified levels. + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test1.xml new file mode 100644 index 000000000..624dd2371 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test1.xml @@ -0,0 +1,11 @@ + + + grandchild1 + + + grandchild2 + + + grandchild3 + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test2.xml new file mode 100644 index 000000000..914950b88 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/lexicon-test2.xml @@ -0,0 +1,11 @@ + + + grandchild4 + + + grandchild5 + + + grandchild6 + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/mildnot1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/mildnot1.xml new file mode 100644 index 000000000..070cfa091 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/mildnot1.xml @@ -0,0 +1 @@ +summer and time in this California city are good. Hiking in that Australian town are not in summer time. My favorite one is Nevada. But sometimes I want to go to trek on islands of Hawaii \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/mlfavicon.png b/test-complete/src/test/java/com/marklogic/javaclient/data/mlfavicon.png new file mode 100644 index 000000000..7e5cc42b5 Binary files /dev/null and b/test-complete/src/test/java/com/marklogic/javaclient/data/mlfavicon.png differ diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/module.xqy b/test-complete/src/test/java/com/marklogic/javaclient/data/module.xqy new file mode 100644 index 000000000..9f8f837d0 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/module.xqy @@ -0,0 +1,9 @@ +xquery version "1.0-ml"; + +module namespace my = "http://my.test.module"; +declare function my:useless() +{ + let $x := (1,2,3,4,5) + return subsequence($x, 2) +}; + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-original.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-original.xml new file mode 100644 index 000000000..1bc8ca5f2 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-original.xml @@ -0,0 +1,7 @@ + + + ¥200 + habañero + + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-updated.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-updated.xml new file mode 100644 index 000000000..515d26638 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte-updated.xml @@ -0,0 +1,8 @@ + + + ¥200 + habañero + + + ひらがな + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte1.xml new file mode 100644 index 000000000..21f83c459 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte1.xml @@ -0,0 +1,6 @@ + + 万里长城 + 5 + 第一 +

中国长城是一系列的石雕,砖雕,夯实土,木,和其他材料,一般都建部分沿整个中国历史的北部边界,东到西线,以保护中国的帝国或作出的防御工事对各种游牧群体,或通过各种好战的民族或势力的军事入侵入侵其典型状态

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte2.xml new file mode 100644 index 000000000..41b9eac64 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte2.xml @@ -0,0 +1,6 @@ + + 上海 + 9 + 第二 +

上海是中国人民共和国(“中国”)最大的城市按人口和最大的城市在世界人口适当

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte3.xml new file mode 100644 index 000000000..9dd6d2117 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/multibyte3.xml @@ -0,0 +1,6 @@ + + 武汉 + 1 + 第三 +

由于其在国内运输的关键作用,武汉有时也被称为“中国的芝加哥。它是公认的中国中部地区的政治,经济,金融,文化,教育和交通中心

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/myJSONFile.json b/test-complete/src/test/java/com/marklogic/javaclient/data/myJSONFile.json new file mode 100644 index 000000000..caea3e8d4 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/myJSONFile.json @@ -0,0 +1,7 @@ +{ +"employees": [ +{ "firstName":"John" , "lastName":"Doe" }, +{ "firstName":"Ann" , "lastName":"Smith" }, +{ "firstName":"Bob" , "lastName":"Foo" } +] +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex1.xml new file mode 100644 index 000000000..b9fe5979d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex1.xml @@ -0,0 +1,5 @@ + + 111 + Aries + Yuwono + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex2.xml new file mode 100644 index 000000000..6c0ee1193 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/pathindex2.xml @@ -0,0 +1,5 @@ + + 132 + Aries + Li + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/property1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/property1.xml new file mode 100644 index 000000000..3c931d267 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/property1.xml @@ -0,0 +1,5 @@ + + Shanghai + 0056 +

Shanghai is a great city

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/property2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/property2.xml new file mode 100644 index 000000000..06ccc9d1f --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/property2.xml @@ -0,0 +1,5 @@ + + Tokyo + 0071 +

Tokyo is quite expensive to live

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/property3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/property3.xml new file mode 100644 index 000000000..e5187a862 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/property3.xml @@ -0,0 +1,5 @@ + + Seoul + 0089 +

Seoul is on the south

+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/readme.txt b/test-complete/src/test/java/com/marklogic/javaclient/data/readme.txt new file mode 100644 index 000000000..eceec8f7e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/readme.txt @@ -0,0 +1,41 @@ +Copyright 2012 MarkLogic Corporation. All Rights Reserved. + +MarkLogic Client API for Java version ${project.version} + +This release constitutes an early-access release subject to the terms of your +agreement. + +This distribution contains code and basic documentation for Client API for Java + +The directory structure is organized as follows: + +docs/ + This directory contains the API documentation (Javadoc). + +example/ + This directory contains cookbook examples and supporting data as well as + examples of content representation extensions. Please see the README.txt + file in the directory for more detail. + +lib/ + This directory contains two jar files. + + * client-api-java-1.0-SNAPSHOT-jar-with-dependencies.jar contains the classes + for the API as well as classes from library dependencies. + + * client-api-java-1.0-SNAPSHOT.jar contains only the classes for the API. + +You are also encouraged to join the MarkLogic developer mailing list: + + http://community.marklogic.com/discuss/ + +Notes: + +At this time, the QueryOptions class provides a representation for query options +read from the database but cannot be used to write query options to the database. +Instead, create query options as an XML or JSON structure. Please see the +QueryOptions and StringOptionsSearch cookbook examples as well as the +query-options-template.xml template file. + +=================================================================== +MarkLogic Corp, http://marklogic.com diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy b/test-complete/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy new file mode 100644 index 000000000..7f534257c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/result-decorator-test.xqy @@ -0,0 +1,86 @@ +xquery version "1.0-ml"; +module namespace rd = "http://my.extension/namespace"; + +declare namespace search = "http://marklogic.com/appservices/search"; + +declare function rd:decorate( + $uri as xs:anyURI +) as node()* +{ + let $format := xdmp:uri-format($uri) + let $mimetype := xdmp:uri-content-type($uri) + return ( + attribute result-decorator { "true" } + + ) +}; + +declare function rd:decorator( + $uri as xs:anyURI + ) as node()* +{ + let $format := xdmp:uri-format($uri) + let $mimetype := xdmp:uri-content-type($uri) + return ( + attribute href { concat("/documents/are/here?uri=", $uri) }, + + if (empty($mimetype)) then () + else attribute mimetype {$mimetype}, + + if (empty($format)) then () + else attribute format { $format }, + element my-elem { "Result Decorated" } + ) +}; + +declare function rd:decoratorWithoutMimeType( + $uri as xs:anyURI + ) as node()* +{ + let $format := xdmp:uri-format($uri) + let $mimetype := xdmp:uri-content-type($uri) + return ( + attribute href { concat("/documents/are/here?uri=", $uri) }, + + if (empty($mimetype)) then () + else attribute mimetype {"Null"}, + + if (empty($format)) then () + else attribute format { $format }, + element my-elem { "Result Decorated" } + ) +}; + +declare function rd:decorate-element( + $uri as xs:anyURI +) as node()* +{ + let $format := xdmp:uri-format($uri) + let $mimetype := xdmp:uri-content-type($uri) + return ( + element search:href { concat("/documents/are/here?uri=", $uri) }, + + if (empty($mimetype)) then () + else element search:mimetype {$mimetype}, + + if (empty($format)) then () + else element search:format { $format } + ) +}; + +declare function rd:decorate-with-attribute( + $uri as xs:anyURI +) as node()* +{ + let $format := xdmp:uri-format($uri) + let $mimetype := xdmp:uri-content-type($uri) + return ( + attribute href { concat("/documents/are/here?uri=", $uri) }, + + if (empty($mimetype)) then () + else attribute mimetype {$mimetype}, + + if (empty($format)) then () + else attribute format { $format } + ) +}; \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/suggestion1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/suggestion1.xml new file mode 100644 index 000000000..f9cc4b440 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/suggestion1.xml @@ -0,0 +1,7 @@ + + act + actor + acting + actress + apricott + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/text-original.txt b/test-complete/src/test/java/com/marklogic/javaclient/data/text-original.txt new file mode 100644 index 000000000..0345e0c80 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/text-original.txt @@ -0,0 +1 @@ +hello world, welcome to java API diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/text-updated.txt b/test-complete/src/test/java/com/marklogic/javaclient/data/text-updated.txt new file mode 100644 index 000000000..ecdb88877 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/text-updated.txt @@ -0,0 +1 @@ +hello world, welcome to java API after new updates diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandle.txt b/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandle.txt new file mode 100644 index 000000000..0345e0c80 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandle.txt @@ -0,0 +1 @@ +hello world, welcome to java API diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandleUpdated.txt b/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandleUpdated.txt new file mode 100644 index 000000000..ecdb88877 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/textReaderHandleUpdated.txt @@ -0,0 +1 @@ +hello world, welcome to java API after new updates diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test1.xml new file mode 100644 index 000000000..610bf25b6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test1.xml @@ -0,0 +1,7 @@ + + + 1.1 + 1 + Alaska + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test2.xml new file mode 100644 index 000000000..c3d54a4e5 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test2.xml @@ -0,0 +1,7 @@ + + + 1.1 + 3 + Birmingham + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test3.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test3.xml new file mode 100644 index 000000000..976ab926e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test3.xml @@ -0,0 +1,7 @@ + + + 1.2 + 3 + Birmingham + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test4.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test4.xml new file mode 100644 index 000000000..6ab88ccc6 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/tuples-test4.xml @@ -0,0 +1,7 @@ + + + 1.2 + 3 + Alaska + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc.xml new file mode 100644 index 000000000..fc6e0421c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc.xml @@ -0,0 +1,10 @@ + + + The Lord of The Ring + J.R.R. Tolkien + + + The Quest of Narnia + C.S. Lewis + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc2.xml new file mode 100644 index 000000000..0fe5565fe --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/value-constraint-doc2.xml @@ -0,0 +1,10 @@ + + + The Lord of The Rings + Some authors + + + Indiana Jones + Steven Spielberg + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc1.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc1.xml new file mode 100644 index 000000000..b6cdcf3bf --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc1.xml @@ -0,0 +1,12 @@ + +
+ This is some title + Frank Chores + Paris is the city on France +
+
+ Another article + Judy Lewis + Froggy the animal +
+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc2.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc2.xml new file mode 100644 index 000000000..19d69477e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/word-constraint-doc2.xml @@ -0,0 +1,12 @@ + +
+ Le Mans + Bud Cassore + Racing car of the year +
+
+ Yosemite On Beyond + John Muir + nature is so good +
+
\ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original-test.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original-test.xml new file mode 100644 index 000000000..1e9891e15 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original-test.xml @@ -0,0 +1,4 @@ + + + noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original.xml new file mode 100644 index 000000000..f3d24228f --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-original.xml @@ -0,0 +1,4 @@ + + + noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated-test.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated-test.xml new file mode 100644 index 000000000..14ab833b3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated-test.xml @@ -0,0 +1,4 @@ + + + fried noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated.xml new file mode 100644 index 000000000..388b01ee1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xml-updated.xml @@ -0,0 +1,4 @@ + + + fried noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandle.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandle.xml new file mode 100644 index 000000000..f3d24228f --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandle.xml @@ -0,0 +1,4 @@ + + + noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandleUpdated.xml b/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandleUpdated.xml new file mode 100644 index 000000000..388b01ee1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/data/xmlReaderHandleUpdated.xml @@ -0,0 +1,4 @@ + + + fried noodle + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-original.xml b/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-original.xml new file mode 100644 index 000000000..10109cd02 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-original.xml @@ -0,0 +1,21 @@ + + + coll1 + coll2 + + + + app-user + update + read + + + + application/msword + text subfiles HD-HTML + Microsoft Office Word + MarkLogic + Mark Logic Corporation + 5 + + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-updated.xml b/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-updated.xml new file mode 100644 index 000000000..502cda207 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/metadata/metadata-updated.xml @@ -0,0 +1,26 @@ + + + coll1 + coll3 + + + + infostudio-user + update + read + + + app-user + read + + + + application/msword + text subfiles HD-HTML + Microsoft Office Word + Aries + QA + 2 + + 23 + \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.json b/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.json new file mode 100644 index 000000000..6b4add696 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.json @@ -0,0 +1 @@ +{"$query":{"id":"0011, "$response":{"$extract":{"title":{}, "id":{}, "p":{}, "popularity":{}}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.xml b/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.xml new file mode 100644 index 000000000..83e54ac63 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/WrongQbe.xml @@ -0,0 +1,11 @@ + + + <q:word>Vannevar</q:word> + 0011 +

atlantic

+ 3 +
+ + <id/><p/><popularity/></q:extract> + </q:response> +</q:qbe> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/payload.json b/test-complete/src/test/java/com/marklogic/javaclient/qbe/payload.json new file mode 100644 index 000000000..c293e9b56 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/payload.json @@ -0,0 +1,13 @@ +{ + "$query": + "title":{"$word":"Vannevar"}, + {"id":"0011"}, + "p":{"$word":"atlantic"}, + "popularity":{"$gt":3}, + "$response":{ + "$extract":{ + "title":{}, + "id":{}, + "p":{}, + "popularity":{}}} + } \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.json b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.json new file mode 100644 index 000000000..f02bd1808 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.json @@ -0,0 +1 @@ +{"$query":{"id":"0011"}, "$response":{"$extract":{"title":{}, "id":{}, "p":{}, "popularity":{}}}} diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.xml b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.xml new file mode 100644 index 000000000..d56536620 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe1.xml @@ -0,0 +1,11 @@ +<q:qbe xmlns:q="http://marklogic.com/appservices/querybyexample"> + <q:query> + <title><q:word>Vannevar</q:word> + 0011 +

atlantic

+ 3 + + + <id/><p/><popularity/></q:extract> + </q:response> +</q:qbe> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe2.xml b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe2.xml new file mode 100644 index 000000000..d56536620 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/qbe/qbe2.xml @@ -0,0 +1,11 @@ +<q:qbe xmlns:q="http://marklogic.com/appservices/querybyexample"> + <q:query> + <title><q:word>Vannevar</q:word> + 0011 +

atlantic

+ 3 + + + <id/><p/><popularity/></q:extract> + </q:response> +</q:qbe> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOpt.xml new file mode 100644 index 000000000..833579300 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOpt.xml @@ -0,0 +1,4 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <page-length>2</page-length> + <transform-results apply="raw"/> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator.xml new file mode 100644 index 000000000..67df6e09e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator.xml @@ -0,0 +1,7 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <page-length>2</page-length> + <transform-results apply="raw"/> + <result-decorator apply="decorator" + ns="http://my.extension/namespace" + at="result-decorator-test.xqy"/> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator1.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator1.xml new file mode 100644 index 000000000..7d25cf788 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/LinkResultDocumentsOptDecorator1.xml @@ -0,0 +1,7 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <page-length>2</page-length> + <transform-results apply="raw"/> + <result-decorator apply="decoratorWithoutMimeType" + ns="http://my.extension/namespace" + at="result-decorator-test.xqy"/> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/absRangeConstraintWithVariousGrammarAndWordQueryOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/absRangeConstraintWithVariousGrammarAndWordQueryOpt.xml new file mode 100644 index 000000000..265e08f1d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/absRangeConstraintWithVariousGrammarAndWordQueryOpt.xml @@ -0,0 +1,28 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="pop"> + <range type="xs:int" facet="true"> + <element ns="" name="popularity"/> + <bucket name="high" ge="5">High</bucket> + <bucket name="medium" ge="3" lt="5">Medium</bucket> + <bucket name="low" ge="1" lt="3">Low</bucket> + </range> + </constraint> + <constraint name="price" > + <range type="xs:decimal" facet="false"> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + <bucket name="high" ge="120">High</bucket> + <bucket name="medium" ge="3" lt="14">Medium</bucket> + <bucket name="low" ge="0" lt="2">Low</bucket> + </range> + </constraint> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt.xml new file mode 100644 index 000000000..9d7087715 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt.xml @@ -0,0 +1,20 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <values name="pop-aggr"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + </values> + <values name="score-aggr"> + <range type="xs:decimal"> + <element ns="http://test.aggr.com" name="score"/> + </range> + </values> + <tuples name="pop-rate-tups"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + <range type="xs:int"> + <element ns="http://test.tups.com" name="rate"/> + </range> + </tuples> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt3Occ.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt3Occ.xml new file mode 100644 index 000000000..35aee064d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt3Occ.xml @@ -0,0 +1,28 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <values name="pop-aggr"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + </values> + <values name="date-val"> + <range type="xs:date"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </values> + <values name="score-aggr"> + <range type="xs:decimal"> + <element ns="http://test.aggr.com" name="score"/> + </range> + </values> + <tuples name="pop-rate-tups"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + <range type="xs:int"> + <element ns="http://test.tups.com" name="rate"/> + </range> + <range type="xs:decimal"> + <element ns="http://test.aggr.com" name="score"/> + </range> + </tuples> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt5Occ.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt5Occ.xml new file mode 100644 index 000000000..72bd4949a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/aggregatesOpt5Occ.xml @@ -0,0 +1,45 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <values name="pop-aggr"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + </values> + <values name="title-val"> + <range type="xs:string"> + <element ns="" name="title"/> + </range> + </values> + <values name="date-val"> + <range type="xs:date"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </values> + <values name="score-aggr"> + <range type="xs:decimal"> + <element ns="http://test.aggr.com" name="score"/> + </range> + </values> + <values name="price-aggr"> + <range type="xs:decimal"> + <element ns="http://cloudbank.com" name="price"/> + </range> + </values> + <tuples name="pop-rate-score-date-tups"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + <range type="xs:int"> + <element ns="http://test.tups.com" name="rate"/> + </range> + <range type="xs:decimal"> + <element ns="http://test.aggr.com" name="score"/> + </range> + <range type="xs:date"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + <range type="xs:decimal"> + <element ns="" name="title"/> + </range> + </tuples> + +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.json b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.json new file mode 100644 index 000000000..4a925190a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.json @@ -0,0 +1 @@ +{"options":{"sort-order":[{"element":{"ns":"", "name":"title"}}], "constraint":[{"name":"id", "value":{"element":{"ns":"", "name":"id"}}},{"name":"date", "range":{"type":"xs:date", "facet":false, "element":{"ns":"http:\/\/purl.org\/dc\/elements\/1.1\/", "name":"date"}}},{"name":"coll", "collection":{"prefix":"http:\/\/test.com\/", "facet":true}},{"name":"para", "word":{"term-option":["case-insensitive"], "field":{"name":"para"}}},{"name":"pop", "range":{"type":"xs:int", "facet":true, "bucket":[{"name":"high", "ge":"5", "label":"High"},{"name":"medium", "ge":"3", "lt":"5", "label":"Medium"},{"name":"low", "ge":"1", "lt":"3", "label":"Low"}], "element":{"ns":"", "name":"popularity"}}},{"name":"price", "range":{"type":"xs:decimal", "facet":false, "bucket":[{"name":"high", "ge":"120", "label":"High"},{"name":"medium", "ge":"3", "lt":"14", "label":"Medium"},{"name":"low", "ge":"0", "lt":"2", "label":"Low"}], "element":{"ns":"http:\/\/cloudbank.com", "name":"price"}, "attribute":{"ns":"", "name":"amt"}}},{"name":"ntitle", "word":{"element":{"ns":"", "name":"title"}}}], "return-metrics":false, "return-qtext":false, "debug":true, "transform-results":{"apply":"raw"}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.xml new file mode 100644 index 000000000..b635bbf2d --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/appservicesConstraintCombinationOpt.xml @@ -0,0 +1,50 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <debug>true</debug> + <transform-results apply="raw"/> + <sort-order> + <element ns="" name="title"/> + </sort-order> + <constraint name="id"> + <value> + <element ns="" name="id"/> + </value> + </constraint> + <constraint name="date"> + <range type="xs:date" facet="false"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </constraint> + <constraint name="coll"> + <collection prefix="http://test.com/" facet="true"/> + </constraint> + <constraint name="para"> + <word> + <field name="para"/> + <term-option>case-insensitive</term-option> + </word> + </constraint> + <constraint name="pop"> + <range type="xs:int" facet="true"> + <element ns="" name="popularity"/> + <bucket name="high" ge="5">High</bucket> + <bucket name="medium" ge="3" lt="5">Medium</bucket> + <bucket name="low" ge="1" lt="3">Low</bucket> + </range> + </constraint> + <constraint name="price" > + <range type="xs:decimal" facet="false"> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + <bucket name="high" ge="120">High</bucket> + <bucket name="medium" ge="3" lt="14">Medium</bucket> + <bucket name="low" ge="0" lt="2">Low</bucket> + </range> + </constraint> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/bug21183Opt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/bug21183Opt.xml new file mode 100644 index 000000000..14f4e9866 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/bug21183Opt.xml @@ -0,0 +1,4 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <page-length>1</page-length> + <transform-results apply="raw"/> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithFacetOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithFacetOpt.xml new file mode 100644 index 000000000..4cba53ad7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithFacetOpt.xml @@ -0,0 +1,9 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="coll"> + <collection prefix="http://test.com/"/> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithNoFacetOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithNoFacetOpt.xml new file mode 100644 index 000000000..42c00581b --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithNoFacetOpt.xml @@ -0,0 +1,9 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="coll"> + <collection prefix="http://test.com/" facet="false"/> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithWordConstraintAndGoogleGrammarOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithWordConstraintAndGoogleGrammarOpt.xml new file mode 100644 index 000000000..177ab423b --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/collectionConstraintWithWordConstraintAndGoogleGrammarOpt.xml @@ -0,0 +1,14 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="coll"> + <collection prefix="http://test.com/" facet="false"/> + </constraint> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/constraintCombinationOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/constraintCombinationOpt.xml new file mode 100644 index 000000000..a225ba2f5 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/constraintCombinationOpt.xml @@ -0,0 +1,29 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="flavor"> + <value> + <element ns="http://example.com" name="flavor-descriptor"/> + </value> + </constraint> + <constraint name="intitle"> + <word> + <element ns="http://example.com" name="title"/> + </word> + </constraint> + <constraint name="heat"> + <range type="xs:int"> + <element ns="http://example.com" name="scoville"/> + <bucket name="mild" lt="500">Mild (less than 500)</bucket> + <bucket name="moderate" ge="500" lt="2500">Moderate (500 - 2500)</bucket> + <bucket name="hot" ge="2500" lt="8000">Hot (2500-8000)</bucket> + <bucket name="extra-hot" ge="8000">Extra Hot (8000+)</bucket> + </range> + </constraint> + <constraint name="contributor"> + <collection prefix="http://bbq.com/contributor/"/> + </constraint> + <constraint name="summary"> + <word> + <field name="bbqtext"/> + </word> + </constraint> + </options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/containerConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/containerConstraintOpt.xml new file mode 100644 index 000000000..393ab4852 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/containerConstraintOpt.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <constraint name="title-contain"> + <container> + <element name="title" ns="" /> + </container> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintOpt.xml new file mode 100644 index 000000000..e496f7bf0 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintOpt.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="summary"> + <word> + <field name="bbqtext"/> + </word> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintWithSnippetAndVariousGrammarAndWordQueryOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintWithSnippetAndVariousGrammarAndWordQueryOpt.xml new file mode 100644 index 000000000..269279d9f --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/fieldConstraintWithSnippetAndVariousGrammarAndWordQueryOpt.xml @@ -0,0 +1,17 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="snippet"/> + <constraint name="para"> + <word> + <field name="para"/> + <term-option>case-insensitive</term-option> + </word> + </constraint> + <constraint name="id"> + <value> + <element ns="" name="id"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/geoConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/geoConstraintOpt.xml new file mode 100644 index 000000000..76a0a2735 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/geoConstraintOpt.xml @@ -0,0 +1,72 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="geo-elem"> + <geo-elem> + <element ns="" name="g-elem-point"/> + </geo-elem> + </constraint> + <constraint name="geo-elem-child"> + <geo-elem> + <parent ns="" name="g-elem-child-parent"/> + <element ns="" name="g-elem-child-point"/> + </geo-elem> + </constraint> + <constraint name="geo-elem-pair"> + <geo-elem-pair> + <parent ns="" name="g-elem-pair"/> + <lat ns="" name="lat"/> + <lon ns="" name="long"/> + </geo-elem-pair> + </constraint> + <constraint name="geo-attr-pair"> + <geo-attr-pair> + <parent ns="" name="g-attr-pair"/> + <lat ns="" name="lat"/> + <lon ns="" name="long"/> + </geo-attr-pair> + </constraint> + <return-metrics>false</return-metrics> + <constraint name="eq-name"> + <element-query ns="" name="name"/> + </constraint> + <constraint name="eq-desc"> + <element-query ns="" name="description"/> + </constraint> + <constraint name="eq-person"> + <element-query ns="" name="person"/> + </constraint> + <constraint name="color"> + <value> + <element ns="" name="color"/> + </value> + </constraint> + <constraint name="height"> + <range type="xs:int"> + <element ns="" name="height1"/> + </range> + </constraint> + <constraint name="bucket_height"> + <range type="xs:int"> + <element ns="" name="height1"/> + <bucket name="tall" ge="21">tall (21+)</bucket> + <bucket name="short" lt="21">short (0-21)</bucket> + </range> + </constraint> + <constraint name="word_const"> + <word> + <element ns="" name="text"/> + </word> + </constraint> + <constraint name="field_const"> + <word> + <field name="description"/> + </word> + </constraint> + <constraint name="coll"> + <collection prefix="http://coll/"/> + </constraint> + <constraint name="prop"> + <properties/> + </constraint> + <page-length>25</page-length> + <debug>true</debug> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/jsonConverterOpt.json b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/jsonConverterOpt.json new file mode 100644 index 000000000..2e7ecc3bf --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/jsonConverterOpt.json @@ -0,0 +1 @@ +{"options":{"_children":[{"values":{"_attributes":{"name":"speaker"}, "_children":[{"range":{"_attributes":{"type":"xs:string"}, "_children":[{"element":{"_attributes":{"ns":"", "name":"SPEAKER"}}}]}}]}}]}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/mildNotOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/mildNotOpt.xml new file mode 100644 index 000000000..ea9c38985 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/mildNotOpt.xml @@ -0,0 +1,6 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <debug>true</debug> + <transform-results apply="raw"/> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/multibyteSearchOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/multibyteSearchOpt.xml new file mode 100644 index 000000000..2a95606c7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/multibyteSearchOpt.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="mult-title"> + <word> + <element ns="" name="title"/> + </word> + </constraint> + <constraint name="mult-pop"> + <range type="xs:int"> + <element ns="" name="popularity"/> + <!-- <bucket name="低" lt="5">低</bucket> + <bucket name="中" ge="5" lt="10">中</bucket> + <bucket name="高" ge="10" lt="15">高</bucket> --> + <bucket name="low" lt="5">低</bucket> + <bucket name="medium" ge="5" lt="10">中</bucket> + <bucket name="high" ge="10" lt="15">高</bucket> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/pathIndexConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/pathIndexConstraintOpt.xml new file mode 100644 index 000000000..07cf8b823 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/pathIndexConstraintOpt.xml @@ -0,0 +1,7 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="pindex"> + <range type="xs:string" collation="http://marklogic.com/collation/"> + <path-index>/Employee/fn</path-index> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/propertiesSearchWordOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/propertiesSearchWordOpt.xml new file mode 100644 index 000000000..eda90b517 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/propertiesSearchWordOpt.xml @@ -0,0 +1,16 @@ +<options xmlns="http://marklogic.com/appservices/search"> +<fragment-scope>properties</fragment-scope> + <constraint name="city-property"> + <word> + <element ns="" name="city"/> + </word> + </constraint> + <constraint name="pop"> + <range type="xs:int"> + <element ns="" name="popularity"/> + <bucket name="low" lt="5">Low</bucket> + <bucket name="medium" ge="5" lt="10">Medium</bucket> + <bucket name="high" ge="10" lt="15">High</bucket> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/queryValidationOpt.json b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/queryValidationOpt.json new file mode 100644 index 000000000..741ef6f60 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/queryValidationOpt.json @@ -0,0 +1,32 @@ +{ + "options": { + "constraint": [ + { + "name": "para", + "word": { + "term-option": [ + "case-insensitive" + ], + "field": { + "name": "para" + } + } + }, + { + "name": "id", + "value": { + "element": { + "ns": "", + "name": "id" + } + } + } + ], + "return-metrics": false, + "debug": true, + "return-qtext": false, + "transform-results": { + "apply": "snippet" + } + } +} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeAbsoluteBucketConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeAbsoluteBucketConstraintOpt.xml new file mode 100644 index 000000000..51d7020f5 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeAbsoluteBucketConstraintOpt.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="heat"> + <range type="xs:int"> + <element ns="http://example.com" name="scoville"/> + <bucket name="mild" lt="500">Mild (below 500)</bucket> + <bucket name="moderate" ge="500" lt="2500">Moderate (500 - 2500)</bucket> + <bucket name="hot" ge="2500" lt="8000">Hot (2500-8000)</bucket> + <bucket name="extra-hot" ge="8000">Extra Hot (8000+)</bucket> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintIntOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintIntOpt.xml new file mode 100644 index 000000000..251eedf3a --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintIntOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="pop"> + <range type="xs:int"> + <element ns="" name="popularity"/> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeTypeMismatchOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeTypeMismatchOpt.xml new file mode 100644 index 000000000..caa92a984 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeTypeMismatchOpt.xml @@ -0,0 +1,10 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="date"> + <range type="xs:string"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeWithoutIndexSettingsOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeWithoutIndexSettingsOpt.xml new file mode 100644 index 000000000..a1be98a0e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintNegativeWithoutIndexSettingsOpt.xml @@ -0,0 +1,10 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="title"> + <range type="xs:string"> + <element ns="" name="title"/> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintOpt.xml new file mode 100644 index 000000000..6d80c3704 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintOpt.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="rating"> + <range type="xs:decimal"> + <element ns="http://example.com" name="rating"/> + </range> +</constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintWithWordSearchOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintWithWordSearchOpt.xml new file mode 100644 index 000000000..55d46816b --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeConstraintWithWordSearchOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="date"> + <range type="xs:date" facet="false"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeRelativeBucketConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeRelativeBucketConstraintOpt.xml new file mode 100644 index 000000000..051be8d38 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/rangeRelativeBucketConstraintOpt.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="date"> + <range type="xs:dateTime" facet="true"> + <element ns="http://example.com" name="entry"/> + <attribute ns="" name="date"/> + <computed-bucket lt="-P1Y" anchor="start-of-year" name="older">Older</computed-bucket> + <computed-bucket lt="P1Y" ge="P0Y" anchor="start-of-year" name="year">This Year</computed-bucket> + <computed-bucket lt="P1M" ge="P0M" anchor="start-of-month" name="month">This Month</computed-bucket> + <computed-bucket lt="P1D" ge="P0D" anchor="start-of-day" name="today">Today</computed-bucket> + <computed-bucket ge="P0D" anchor="now" name="future">Future</computed-bucket> + <facet-option>descending</facet-option> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/searchReturnResultsFalseOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/searchReturnResultsFalseOpt.xml new file mode 100644 index 000000000..a6fee37c2 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/searchReturnResultsFalseOpt.xml @@ -0,0 +1,8 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> + <return-results>false</return-results> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/setViewOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/setViewOpt.xml new file mode 100644 index 000000000..2c33b82d0 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/setViewOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <transform-results apply="raw"/> + <constraint name="pop"> + <range type="xs:int" facet="true"> + <element ns="" name="popularity"/> + <bucket name="high" ge="5">High</bucket> + <bucket name="medium" ge="3" lt="5">Medium</bucket> + <bucket name="low" ge="1" lt="3">Low</bucket> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt.xml new file mode 100644 index 000000000..72082f913 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt.xml @@ -0,0 +1,7 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <default-suggestion-source> + <range type="xs:string" collation="http://marklogic.com/collation/"> + <element ns="" name="title"/> + </range> + </default-suggestion-source> + </options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt2.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt2.xml new file mode 100644 index 000000000..310360e92 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt2.xml @@ -0,0 +1,8 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <default-suggestion-source> + <range type="xs:decimal"> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </range> + </default-suggestion-source> + </options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt3.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt3.xml new file mode 100644 index 000000000..a63f7b076 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt3.xml @@ -0,0 +1,7 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <default-suggestion-source> + <range type="xs:date"> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </range> + </default-suggestion-source> + </options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt4.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt4.xml new file mode 100644 index 000000000..89176ab72 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/suggestionOpt4.xml @@ -0,0 +1,12 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <default-suggestion-source> + <range type="xs:string" collation="http://marklogic.com/collation/"> + <element ns="http://action/" name="title"/> + </range> + </default-suggestion-source> + <suggestion-source ref="noun"> + <range type="xs:string" collation="http://marklogic.com/collation/"> + <element ns="http://noun/" name="title"/> + </range> + </suggestion-source> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintGoogleGrammarOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintGoogleGrammarOpt.xml new file mode 100644 index 000000000..4e1b4292c --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintGoogleGrammarOpt.xml @@ -0,0 +1,21 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <debug>true</debug> + <constraint name="id"> + <value> + <element ns="" name="id"/> + </value> + </constraint> + <constraint name="date"> + <value> + <element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </value> + </constraint> + <constraint name="title"> + <value> + <element ns="" name="title"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintSpaceSeparatedOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintSpaceSeparatedOpt.xml new file mode 100644 index 000000000..477a59030 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintSpaceSeparatedOpt.xml @@ -0,0 +1,17 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="title"> + <value> + <element ns="" name="title"/> + </value> + </constraint> + <constraint name="price"> + <value> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.json b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.json new file mode 100644 index 000000000..d858f9ef7 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.json @@ -0,0 +1,2 @@ +{"options":{"return-metrics": "false","return-qtext": "false","debug": "true","transform-results": {"apply": "raw"},"constraint": {"name": "id","value": {"element": {"ns": "","name": "id"}}}}} + diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.xml new file mode 100644 index 000000000..c141f0de3 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWildCardOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <debug>true</debug> + <transform-results apply="raw"/> + <constraint name="id"> + <value> + <element ns="" name="id"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithIndexSettingsAndNSOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithIndexSettingsAndNSOpt.xml new file mode 100644 index 000000000..5e390a533 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithIndexSettingsAndNSOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <debug>true</debug> + <constraint name="dt"> + <value> + <element name="date" ns="http://purl.org/dc/elements/1.1/"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithoutIndexSettingsAndNSOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithoutIndexSettingsAndNSOpt.xml new file mode 100644 index 000000000..ca90d6d16 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/valueConstraintWithoutIndexSettingsAndNSOpt.xml @@ -0,0 +1,11 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-qtext>false</return-qtext> + <debug>true</debug> + <transform-results apply="raw"/> + <constraint name="id"> + <value> + <element ns="" name="id"/> + </value> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintOpt.xml new file mode 100644 index 000000000..d9ae1251e --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintOpt.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<options xmlns="http://marklogic.com/appservices/search"> + <constraint name="my-element-word"> + <word> + <element ns="" name="abstract"/> + </word> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexOpt.xml new file mode 100644 index 000000000..301f1ee16 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexOpt.xml @@ -0,0 +1,20 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <sort-order> + <element ns="" name="title"/> + </sort-order> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> + <constraint name="inprice"> + <word> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </word> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexPlanOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexPlanOpt.xml new file mode 100644 index 000000000..c73befb67 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithElementAndAttributeIndexPlanOpt.xml @@ -0,0 +1,21 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <return-plan>true</return-plan> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <sort-order> + <element ns="" name="title"/> + </sort-order> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> + <constraint name="inprice"> + <word> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </word> + </constraint> +</options> diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithNormalWordQueryOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithNormalWordQueryOpt.xml new file mode 100644 index 000000000..4a0f2a2dd --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithNormalWordQueryOpt.xml @@ -0,0 +1,17 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + </word> + </constraint> + <constraint name="inprice"> + <word> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </word> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithTermOptionCaseInsensitiveOpt.xml b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithTermOptionCaseInsensitiveOpt.xml new file mode 100644 index 000000000..fe49d9bf9 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/queryoptions/wordConstraintWithTermOptionCaseInsensitiveOpt.xml @@ -0,0 +1,18 @@ +<options xmlns="http://marklogic.com/appservices/search"> + <return-metrics>false</return-metrics> + <debug>true</debug> + <return-qtext>false</return-qtext> + <transform-results apply="raw"/> + <constraint name="intitle"> + <word> + <element ns="" name="title"/> + <term-option>case-insensitive</term-option> + </word> + </constraint> + <constraint name="price"> + <range type="xs:decimal"> + <element ns="http://cloudbank.com" name="price"/> + <attribute ns="" name="amt"/> + </range> + </constraint> +</options> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.json b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.json new file mode 100644 index 000000000..dd18c9597 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.json @@ -0,0 +1 @@ +{"rule":{"name":"RULE-TEST-1-JSON", "description":"rule for test1 json", "search":{"query":{"word-constraint-query":{"constraint-name":"intitle", "text":"Vannevar"}}, "options":{"constraint":{"name":"intitle", "word":{"element":{"name":"title", "ns":""}}}}}, "rule-metadata":{"rule-number":"one json"}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.xml b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.xml new file mode 100644 index 000000000..99e9fa5b2 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule1.xml @@ -0,0 +1,22 @@ +<rapi:rule xmlns:rapi="http://marklogic.com/rest-api"> + <rapi:name>RULE-TEST-1</rapi:name> + <rapi:description>rule for test1</rapi:description> + <search:search xmlns:search="http://marklogic.com/appservices/search"> + <search:query> + <search:word-constraint-query> + <search:constraint-name>intitle</search:constraint-name> + <search:text>Vannevar</search:text> + </search:word-constraint-query> + </search:query> + <search:options> + <search:constraint name="intitle"> + <search:word> + <search:element name="title" ns=""/> + </search:word> + </search:constraint> + </search:options> + </search:search> + <rapi:rule-metadata> + <rule-number>one</rule-number> + </rapi:rule-metadata> +</rapi:rule> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule2.xml b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule2.xml new file mode 100644 index 000000000..2efab1e98 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule2.xml @@ -0,0 +1,22 @@ +<rapi:rule xmlns:rapi="http://marklogic.com/rest-api"> + <rapi:name>RULE-TEST-2</rapi:name> + <rapi:description>rule for test2</rapi:description> + <search:search xmlns:search="http://marklogic.com/appservices/search"> + <search:query> + <search:range-constraint-query> + <search:constraint-name>date</search:constraint-name> + <search:value>2005-01-01</search:value> + </search:range-constraint-query> + </search:query> + <search:options> + <search:constraint name="date"> + <search:range type="xs:date" facet="false"> + <search:element ns="http://purl.org/dc/elements/1.1/" name="date"/> + </search:range> + </search:constraint> + </search:options> + </search:search> + <rapi:rule-metadata> + <rule-number>two</rule-number> + </rapi:rule-metadata> +</rapi:rule> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.json b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.json new file mode 100644 index 000000000..ecfcbf7ff --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.json @@ -0,0 +1 @@ +{"rule":{"name":"RULE-TEST-3-JSON", "description":"rule for test3 json", "search":{"query":{"word-constraint-query":{"constraint-name":"intitle", "text":"Bush"}}, "options":{"constraint":{"name":"intitle", "word":{"element":{"name":"title", "ns":""}}}}}, "rule-metadata":{"rule-number":"three json"}}} \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.xml b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.xml new file mode 100644 index 000000000..cd08a9429 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/alertRule3.xml @@ -0,0 +1,22 @@ +<rapi:rule xmlns:rapi="http://marklogic.com/rest-api"> + <rapi:name>RULE-TEST-3</rapi:name> + <rapi:description>rule for test3</rapi:description> + <search:search xmlns:search="http://marklogic.com/appservices/search"> + <search:query> + <search:word-constraint-query> + <search:constraint-name>intitle</search:constraint-name> + <search:text>Bush</search:text> + </search:word-constraint-query> + </search:query> + <search:options> + <search:constraint name="intitle"> + <search:word> + <search:element name="title" ns=""/> + </search:word> + </search:constraint> + </search:options> + </search:search> + <rapi:rule-metadata> + <rule-number>three</rule-number> + </rapi:rule-metadata> +</rapi:rule> \ No newline at end of file diff --git a/test-complete/src/test/java/com/marklogic/javaclient/rules/rule-transform.xqy b/test-complete/src/test/java/com/marklogic/javaclient/rules/rule-transform.xqy new file mode 100644 index 000000000..90620fde1 --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/rules/rule-transform.xqy @@ -0,0 +1,25 @@ +xquery version "1.0-ml"; + +module namespace ruleTransform = "http://marklogic.com/rest-api/transform/ruleTransform"; + +declare namespace rapi = "http://marklogic.com/rest-api"; + +declare function ruleTransform:transform( + $context as map:map, + $params as map:map, + $content as document-node() +) as document-node() +{ + let $rules := $content/node()/* + return + document { + element { node-name($content/node()) } { + for $rule-match in $rules + return + element { node-name($rule-match) } { + $rule-match/*, + element transformed-name { $rule-match/rapi:name/text() } + } + } + } +}; diff --git a/test-complete/src/test/java/com/marklogic/javaclient/transforms/search2html.xsl b/test-complete/src/test/java/com/marklogic/javaclient/transforms/search2html.xsl new file mode 100644 index 000000000..b79ae03ea --- /dev/null +++ b/test-complete/src/test/java/com/marklogic/javaclient/transforms/search2html.xsl @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:map="http://marklogic.com/xdmp/map" + xmlns:search="http://marklogic.com/appservices/search" + xmlns="http://www.w3.org/1999/xhtml" + exclude-result-prefixes="map"> + +<xsl:param name="context" as="map:map"/> +<xsl:param name="params" as="map:map"/> + +<xsl:output method="html" + doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" + doctype-system="http://www.w3.org/TR/html4/loose.dtd"/> + +<xsl:template match="/"> + <xsl:sequence select="map:put($context,'output-type','text/html')"/> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="search:response"> + <html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>Custom Search Results + + + + + + + + + + + +
+ MyURI + + MyScore + + MyMatch +
+ + + + + + + + + + + + + + + + + + +