diff --git a/client/src/jaxws/bindings.xml b/client/src/jaxws/bindings.xml
index cf7069ad..a7a86d08 100644
--- a/client/src/jaxws/bindings.xml
+++ b/client/src/jaxws/bindings.xml
@@ -26,5 +26,11 @@
+
+
+
+
+
diff --git a/client/src/main/java/io/cloudsoft/winrm4j/client/EnumerateCommand.java b/client/src/main/java/io/cloudsoft/winrm4j/client/EnumerateCommand.java
new file mode 100644
index 00000000..baab3e1e
--- /dev/null
+++ b/client/src/main/java/io/cloudsoft/winrm4j/client/EnumerateCommand.java
@@ -0,0 +1,235 @@
+package io.cloudsoft.winrm4j.client;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import io.cloudsoft.winrm4j.client.enumeration.EnumerateResponse;
+import io.cloudsoft.winrm4j.client.enumeration.PullResponse;
+import io.cloudsoft.winrm4j.client.wsman.Enumerate;
+import io.cloudsoft.winrm4j.client.wsman.Filter;
+import io.cloudsoft.winrm4j.client.wsman.Items;
+import io.cloudsoft.winrm4j.client.wsman.Locale;
+import io.cloudsoft.winrm4j.client.wsman.OptionSetType;
+import io.cloudsoft.winrm4j.client.wsman.Pull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import static io.cloudsoft.winrm4j.client.WinRmClient.MAX_ENVELOPER_SIZE;
+
+public class EnumerateCommand implements AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(EnumerateCommand.class.getName());
+
+ /**
+ * If no output is available before the wsman:OperationTimeout expires, the server MUST return a WSManFault with the Code attribute equal to "2150858793"
+ * https://msdn.microsoft.com/en-us/library/cc251676.aspx
+ */
+ static final String WSMAN_FAULT_CODE_OPERATION_TIMEOUT_EXPIRED = "2150858793";
+
+ private final WinRm winrm;
+ private final String resourceUri;
+ private final String sessionId;
+ private final long maxElements;
+ private final Supplier operationTimeout;
+ private final Supplier locale;
+ private final Predicate retryReceiveAfterOperationTimeout;
+
+ private final DocumentBuilder documentBuilder;
+
+ public EnumerateCommand(final WinRm winrm,
+ final String resourceUri,
+ final long maxElements,
+ final Supplier operationTimeout,
+ final Supplier locale,
+ final Predicate retryReceiveAfterOperationTimeout) {
+ this.winrm = winrm;
+ this.resourceUri = resourceUri;
+ this.sessionId = "uuid:" + UUID.randomUUID();
+ this.maxElements = maxElements;
+ this.operationTimeout = operationTimeout;
+ this.locale = locale;
+ this.retryReceiveAfterOperationTimeout = retryReceiveAfterOperationTimeout;
+ try {
+ this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new IllegalStateException("Failed to create instance of DocumentBuilder");
+ }
+ }
+
+ public List execute(final String filter, final String dialect) {
+ final EnumerateResponse enumerateResponse = enumerate(filter, dialect);
+ final List result = new ArrayList<>();
+ collectAndIterateEnumeratedResults(result, new EnumerationPullState(
+ resourceUri,
+ maxElements,
+ enumerateResponse.getEnumerationContext(),
+ enumerateResponse.getItems(),
+ enumerateResponse.getEndOfSequence() != null
+ ));
+ return result;
+ }
+
+ private EnumerateResponse enumerate(final String filter, final String dialect) {
+ while (true) {
+ try {
+ final Enumerate enumerate = new Enumerate();
+ enumerate.setFilter(new Filter());
+ enumerate.getFilter().setValue(filter);
+ enumerate.getFilter().setDialect(dialect);
+ enumerate.setMaxElements(maxElements);
+ return winrm.enumerate(
+ enumerate,
+ resourceUri,
+ sessionId,
+ MAX_ENVELOPER_SIZE,
+ operationTimeout.get(),
+ locale.get(),
+ new OptionSetType()
+ );
+ } catch (final SOAPFaultException soapFault) {
+ /**
+ * If such Exception which has a code 2150858793 the client is expected to again trigger immediately a receive request.
+ * https://msdn.microsoft.com/en-us/library/cc251676.aspx
+ */
+ assertFaultCode(soapFault, WSMAN_FAULT_CODE_OPERATION_TIMEOUT_EXPIRED,
+ retryReceiveAfterOperationTimeout);
+ }
+ }
+ }
+
+ private PullResponse pull(final EnumerationPullState state) {
+ while (true) {
+ try {
+ final Pull pull = new Pull();
+ pull.setEnumerationContext(state.getEnumerationContext());
+ pull.setMaxElements(maxElements);
+ return winrm.enumeratePull(
+ pull,
+ state.getResourceId(),
+ sessionId,
+ MAX_ENVELOPER_SIZE,
+ operationTimeout.get(),
+ locale.get(),
+ new OptionSetType()
+ );
+ } catch (final SOAPFaultException soapFault) {
+ /**
+ * If such Exception which has a code 2150858793 the client is expected to again trigger immediately a receive request.
+ * https://msdn.microsoft.com/en-us/library/cc251676.aspx
+ */
+ assertFaultCode(soapFault, WSMAN_FAULT_CODE_OPERATION_TIMEOUT_EXPIRED,
+ retryReceiveAfterOperationTimeout);
+ }
+ }
+ }
+
+ void collectAndIterateEnumeratedResults(final List result, final EnumerationPullState state) {
+
+ final Document doc = documentBuilder.newDocument();
+ final Element root = doc.createElement("results");
+ doc.appendChild(root);
+
+ final Items items = state.getItems();
+ if (items != null) {
+ final List