title: How to efficiently check if a message still exists in Exchange?
body: <p>We have a program that keeps a local copy of a potentially large number of mailboxes by monitoring configurable journal streams through the Exchange Web Service Managed API. 
  These journal streams give us an efficient way to ingest the incoming/outgoing mail for thousands of users.</p>
  
  <p>Periodically we need to check if specific mail messages are still present in Exchange.</p>
  
  <p>We currently do this by using <code>FindItems</code> filtered by the InternetMessageID (which we can get from the envelope in the journal):</p>
  
  <pre class="lang-cs prettyprint-override"><code>var internetMessageIds = new [] {
      "&lt;8ADA5FF6B7C3AB4B8F9BC5AF78206B42010AD1A3@....&gt;",
      "&lt;04A2D0BEB32B69458296B3E48F75732D014F601E@...&gt;",
      "&lt;F04A6B3F2A8AFC42BF4AC18C596A9810749CC4@...&gt;"
  };
  var filter = new SearchFilter.SearchFilterCollection(
      LogicalOperator.Or, 
      internetMessageIds.Select(imid =&gt; 
          new SearchFilter.IsEqualTo(EmailMessageSchema.InternetMessageId, imid)
      )
  );
  
  var exchange = new ExchangeService(PreAuthenticate = true, Credentials = ...);
  exchange.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailbox);
  
  var folderView = new FolderView(1000) { 
      Traversal=FolderTraversal.Deep, 
      PropertySet=BasePropertySet.IdOnly 
  };
  var folders = exchange.FindFolders(WellKnownFolderName.Root, folderView)
      .Where(f =&gt; f.DisplayName == "AllItems" || f.DisplayName == "Deletions" || f.DisplayName == "Purges");
  if (folders.Count() != 3) {
      // fall back to searching all folders
      folders = exchange.FindFolders(WellKnownFolderName.Root, folderView);
  }
  foreach (var folder in folders) {
      var findItemsResult = exchange.FindItems(folder.Id, filter, new ItemView(10));
      foreach (var itemResult in findItemsResult) {
          Console.WriteLine(
              "InternetMessageID={0}, UniqueId={1}", 
              ((EmailMessage)itemResult).InternetMessageId, 
              itemResult.Id.UniqueId
          );
      }
  }
  </code></pre>
  
  <p>As you can see we loop through multiple folders and call <code>FindItems</code> on each. </p>
  
  <p>Initially we always looped through all folders, but we recently optimized the code to use the All Items search folder (if it exists).</p>
  
  <p>That optimization made our "does this message still exist in Exchange?" check faster, but it is still too expensive to run against any non-trivial number of messages. </p>
  
  <ul>
  <li>Checking 3 messages takes about 3 seconds (after establishing the connection and impersonation) when the All Items folder exists. </li>
  <li>Compare that to using <code>BindItems</code> with the UniqueID, which takes less than half a second in my tests. 
  <ul>
  <li>But the UniqueID of a message is not available from the envelope in the journal stream. </li>
  <li>And even if it were, the UniqueID of a message changes when the user moves it to a different folder in their mailbox.</li>
  </ul></li>
  </ul>
  
  <p>Is there a more efficient way to check if a message we've captured from the journal still exists in the recipient's mailbox in Exchange?</p>