@Override
  public ExportResult<MailContainerResource> export(UUID id,
      TokensAndUrlAuthData authData, Optional<ExportInformation> exportInformation) {
    // Create a new gmail service for the authorized user
    Gmail gmail = getOrCreateGmail(authData);

    Messages.List request = null;
    try {
      request = gmail.users().messages().list(USER).setMaxResults(PAGE_SIZE);
    } catch (IOException e) {
      return new ExportResult<>(e);
    }

    if (exportInformation.isPresent() && exportInformation.get().getPaginationData() != null) {
      request.setPageToken(
          ((StringPaginationToken) exportInformation.get().getPaginationData()).getToken());
    }

    ListMessagesResponse response = null;
    try {
      response = request.execute();
    } catch (IOException e) {
      return new ExportResult<>(e);
    }

    List<MailMessageModel> results = new ArrayList<>(response.getMessages().size());
    // TODO: this is a good indication we need to swap the interface
    // as we can't store all the mail messages in memory at once.
    for (Message listMessage : response.getMessages()) {
      Message getResponse = null;
      try {
        getResponse =
            gmail.users().messages().get(USER, listMessage.getId()).setFormat("raw").execute();
      } catch (IOException e) {
        return new ExportResult<>(e);
      }
      // TODO: note this doesn't transfer things like labels
      results.add(new MailMessageModel(getResponse.getRaw(), getResponse.getLabelIds()));
    }

    PaginationData newPage = null;
    ResultType resultType = ResultType.END;
    if (response.getNextPageToken() != null) {
      newPage = new StringPaginationToken(response.getNextPageToken());
      resultType = ResultType.CONTINUE;
    }

    MailContainerResource mailContainerResource = new MailContainerResource(null, results);
    return new ExportResult<>(resultType, mailContainerResource, new ContinuationData(newPage));
  }
@Test
  public void exportMessagesFirstSet() throws IOException {
    setUpSingleMessageResponse();

    // Looking at first page, with at least one page after it
    messageListResponse.setNextPageToken(NEXT_TOKEN);

    // Run test
    ExportResult<MailContainerResource> result =
        googleMailExporter.export(JOB_ID, null, Optional.empty());

    // Check results
    // Verify correct methods were called
    InOrder inOrder = Mockito.inOrder(messages, messageListRequest, get);
    // First request
    inOrder.verify(messages).list(GoogleMailExporter.USER);
    inOrder.verify(messageListRequest).setMaxResults(GoogleMailExporter.PAGE_SIZE);
    verify(messageListRequest, never()).setPageToken(anyString());
    // Second request
    inOrder.verify(messages).get(GoogleMailExporter.USER, MESSAGE_ID);
    inOrder.verify(get).setFormat("raw");
    inOrder.verify(get).execute();

    // Check pagination token
    ContinuationData continuationData = (ContinuationData) result.getContinuationData();
    StringPaginationToken paginationToken =
        (StringPaginationToken) continuationData.getPaginationData();
    assertThat(paginationToken.getToken()).isEqualTo(NEXT_TOKEN);

    // Check messages
    Collection<MailMessageModel> actualMail = result.getExportedData().getMessages();
    assertThat(actualMail.stream().map(MailMessageModel::getRawString).collect(Collectors.toList()))
        .containsExactly(MESSAGE_RAW);
    assertThat(
        actualMail.stream().map(MailMessageModel::getContainerIds).collect(Collectors.toList()))
        .containsExactly(MESSAGE_LABELS);
  }