public void initialize() {
    Monitor monitor = loadMonitor();

    SettingsExtension settingsExtension = getSettingsExtension();
    settingsExtension.initialize();
    WorkerExtensionContext extensionContext =
        new WorkerExtensionContext(settingsExtension, monitor);

    // TODO this should be moved into a service extension
    extensionContext.registerService(HttpTransport.class, new NetHttpTransport());
    extensionContext.registerService(OkHttpClient.class, new OkHttpClient.Builder().build());
    extensionContext.registerService(JsonFactory.class, GsonFactory.getDefaultInstance());

    ServiceLoader.load(ServiceExtension.class)
        .iterator()
        .forEachRemaining(serviceExtension -> serviceExtension.initialize(extensionContext));

    // TODO: verify that this is the cloud extension that is specified in the configuration
    CloudExtension cloudExtension = getCloudExtension();
    cloudExtension.initialize(extensionContext);
    monitor.info(() -> "Using CloudExtension: " + cloudExtension.getClass().getName());

    JobStore jobStore = cloudExtension.getJobStore();
    extensionContext.registerService(JobStore.class, jobStore);
    extensionContext.registerService(TemporaryPerJobDataStore.class, jobStore);

    AppCredentialStore appCredentialStore = cloudExtension.getAppCredentialStore();
    extensionContext.registerService(AppCredentialStore.class, appCredentialStore);

    List<TransferExtension> transferExtensions = getTransferExtensions(monitor);

    // Load security extension and services
    SecurityExtension securityExtension =
        SecurityExtensionLoader.getSecurityExtension(extensionContext);
    monitor.info(() -> "Using SecurityExtension: " + securityExtension.getClass().getName());

    IdempotentImportExecutorExtension idempotentImportExecutorExtension =
        IdempotentImportExecutorLoader.load(extensionContext);

    extensionContext.registerService(
        IdempotentImportExecutorExtension.class, idempotentImportExecutorExtension);

    monitor.info(
        () -> "Using IdempotentImportExecutor: " + idempotentImportExecutorExtension.getClass().getName());

    // TODO: make configurable
    SymmetricKeyGenerator symmetricKeyGenerator = new AesSymmetricKeyGenerator(monitor);

    JobHooks jobHooks = loadJobHooks();

    Injector injector = null;
    try {
      injector =
          Guice.createInjector(
              new WorkerModule(
                  extensionContext,
                  cloudExtension,
                  transferExtensions,
                  securityExtension,
                  idempotentImportExecutorExtension,
                  symmetricKeyGenerator,
                  jobHooks,
                  new TransferCompatibilityProvider()));
    } catch (Exception e) {
      monitor.severe(() -> "Unable to initialize Guice in Worker", e);
      throw e;
    }
    worker = injector.getInstance(Worker.class);

    // Reset the JobMetadata in case set previously when running SingleVMMain
    JobMetadata.reset();
  }
Main class to bootstrap a portability transfer worker that will operate on a single job whose
state is held in {@link JobMetadata}.
portability-transfer/src/main/java/org/datatransferproject/transfer/WorkerMain.java