@Override
  public void initialize(ExtensionContext context) {
    // Note: initialize could be called twice in an account migration scenario where we import and
    // export to the same service provider. So just return rather than throwing if called multiple
    // times.
    if (initialized) return;

    final double maxWritesPerSecond =  context.getSetting("msoftMaxWritesPerSecond", 1.0);
    TemporaryPerJobDataStore jobStore = context.getService(TemporaryPerJobDataStore.class);
    HttpTransport httpTransport = context.getService(HttpTransport.class);

    JsonFactory jsonFactory = context.getService(JsonFactory.class);
    TransformerService transformerService = new TransformerServiceImpl();
    OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
    ObjectMapper mapper = new ObjectMapper();

    // TODO(jzacsh) does anyone really want this across importer/exporters of
    // this adapter? we can probably delete this and pass a fresh .build() to
    // every constructor below, right?
    final OkHttpClient sharedHttpClient = httpClientBuilder.build();

    AppCredentials appCredentials;
    try {
      appCredentials =
          context
              .getService(AppCredentialStore.class)
              .getAppCredentials("MICROSOFT_KEY", "MICROSOFT_SECRET");
    } catch (IOException e) {
      Monitor monitor = context.getMonitor();
      monitor.info(
          () ->
              "Unable to retrieve Microsoft AppCredentials. Did you set MICROSOFT_KEY and MICROSOFT_SECRET?");
      return;
    }

    // Create the MicrosoftCredentialFactory with the given {@link AppCredentials}.
    MicrosoftCredentialFactory credentialFactory =
        new MicrosoftCredentialFactory(httpTransport, jsonFactory, appCredentials);
    JobFileStream jobFileStream = new JobFileStream();

    Monitor monitor = context.getMonitor();

    ImmutableMap.Builder<DataVertical, Importer> importBuilder = ImmutableMap.builder();
    importBuilder.put(
        CONTACTS,
        new MicrosoftContactsImporter(BASE_GRAPH_URL, sharedHttpClient, mapper, transformerService));
    importBuilder.put(
        CALENDAR,
        new MicrosoftCalendarImporter(BASE_GRAPH_URL, sharedHttpClient, mapper, transformerService));
    // WARNING: do not use this importer; it will be deleted soon by jzacsh@ in favor of the actually maintained Media variant.
    importBuilder.put(
        PHOTOS, new MicrosoftPhotosImporter(BASE_GRAPH_URL, sharedHttpClient, mapper, jobStore, monitor,
          credentialFactory, jobFileStream));
    importBuilder.put(MEDIA, new MicrosoftMediaImporter(BASE_GRAPH_URL, httpClientBuilder, mapper, jobStore, monitor,
          credentialFactory, jobFileStream, maxWritesPerSecond));
    importerMap = importBuilder.build();

    ImmutableMap.Builder<DataVertical, Exporter> exporterBuilder = ImmutableMap.builder();
    exporterBuilder.put(
        CONTACTS,
        new MicrosoftContactsExporter(BASE_GRAPH_URL, sharedHttpClient, mapper, transformerService));
    exporterBuilder.put(
        CALENDAR,
        new MicrosoftCalendarExporter(BASE_GRAPH_URL, sharedHttpClient, mapper, transformerService));
    // WARNING: do not use this importer; it will be deleted soon by jzacsh@ in favor of the actually maintained Media variant.
    exporterBuilder.put(PHOTOS, new MicrosoftPhotosExporter(credentialFactory, jsonFactory, monitor));
    exporterBuilder.put(MEDIA, new MicrosoftMediaExporter(credentialFactory, jsonFactory, monitor));
    exporterBuilder.put(
        OFFLINE_DATA, new MicrosoftOfflineDataExporter(BASE_GRAPH_URL, sharedHttpClient, mapper));

    exporterMap = exporterBuilder.build();

    initialized = true;
  }
Bootstraps the Microsoft data transfer services.
extensions/data-transfer/portability-data-transfer-microsoft/src/main/java/org/datatransferproject/transfer/microsoft/MicrosoftTransferExtension.java