public List<PendingSet> QueryPendingSets(string localWorkspaceName, string localWorkspaceOwner,
                                                 string queryWorkspaceName, string ownerName,
                                                 ItemSpec[] itemSpecs, bool generateDownloadUrls)
        {
            var invoker = new SoapInvoker(this);
            var msg = invoker.CreateEnvelope("QueryPendingSets");
            msg.Add(new XElement(MessageNs + "localWorkspaceName", localWorkspaceName));
            msg.Add(new XElement(MessageNs + "localWorkspaceOwner", localWorkspaceOwner));
            msg.Add(new XElement(MessageNs + "queryWorkspaceName", queryWorkspaceName));
            msg.Add(new XElement(MessageNs + "ownerName", ownerName));
            msg.Add(new XElement(MessageNs + "itemSpecs", itemSpecs.Select(i => i.ToXml(MessageNs + "ItemSpec"))));
            msg.Add(new XElement(MessageNs + "generateDownloadUrls", generateDownloadUrls.ToLowString()));

            var result = invoker.InvokeResult();
            return new List<PendingSet>(result.Elements(MessageNs + "PendingSet").Select(PendingSet.FromXml));
//            var pendingChangesElements = result.Descendants(MessageNs + "PendingChange");
//            var failuresElements = result.Descendants(MessageNs + "PendingChange");
//
//            var changes = new List<PendingChange>(pendingChangesElements.Select(el => PendingChange.FromXml(el)));
//            var faillist = new List<Failure>(failuresElements.Select(el => Failure.FromXml(el)));
//            return new Tuple<List<PendingChange>, List<Failure>>(changes, faillist);
        }
        //    <QueryItems xmlns="http://schemas.microsoft.com/TeamFoundation/2005/06/VersionControl/ClientServices/03">
        //      <workspaceName>string</workspaceName>
        //      <workspaceOwner>string</workspaceOwner>
        //      <items>
        //        <ItemSpec item="string" recurse="None or OneLevel or Full" did="int" />
        //        <ItemSpec item="string" recurse="None or OneLevel or Full" did="int" />
        //      </items>
        //      <version />
        //      <deletedState>NonDeleted or Deleted or Any</deletedState>
        //      <itemType>Any or Folder or File</itemType>
        //      <generateDownloadUrls>boolean</generateDownloadUrls>
        //      <options>int</options>
        //    </QueryItems>
        public List<Item> QueryItems(string workspaceName, string workspaceOwner, ItemSpec[] itemSpecs, VersionSpec versionSpec,
                                     DeletedState deletedState, ItemType itemType, 
                                     bool includeDownloadInfo)
        {
            var invoker = new SoapInvoker(this);
            var msg = invoker.CreateEnvelope("QueryItems");
            if (!string.IsNullOrEmpty(workspaceName))
                msg.Add(new XElement(MessageNs + "workspaceName", workspaceName));
            if (!string.IsNullOrEmpty(workspaceOwner))
                msg.Add(new XElement(MessageNs + "workspaceOwner", workspaceOwner));
            msg.Add(new XElement(MessageNs + "items", itemSpecs.Select(itemSpec => itemSpec.ToXml(MessageNs + "ItemSpec"))));
            msg.Add(versionSpec.ToXml(MessageNs + "version"));
            msg.Add(new XElement(MessageNs + "deletedState", deletedState));
            msg.Add(new XElement(MessageNs + "itemType", itemType));
            msg.Add(new XElement(MessageNs + "generateDownloadUrls", includeDownloadInfo.ToLowString()));

            var result = invoker.InvokeResult();
            return result.Descendants(MessageNs + "Item").Select(Item.FromXml).ToList();
        }