@Override
  public Image call() throws LayerPropertyNotFoundException {
    try (ProgressEventDispatcher ignored =
            progressEventDispatcherFactory.create("building image format", 1);
        TimerEventDispatcher ignored2 =
            new TimerEventDispatcher(buildContext.getEventHandlers(), DESCRIPTION)) {
      // Constructs the image.
      Image.Builder imageBuilder = Image.builder(buildContext.getTargetFormat());

      // Base image layers
      baseImageLayers.forEach(imageBuilder::addLayer);

      // Passthrough config and count non-empty history entries
      int nonEmptyLayerCount = 0;
      for (HistoryEntry historyObject : baseImage.getHistory()) {
        imageBuilder.addHistory(historyObject);
        if (!historyObject.hasCorrespondingLayer()) {
          nonEmptyLayerCount++;
        }
      }
      imageBuilder
          .setArchitecture(baseImage.getArchitecture())
          .setOs(baseImage.getOs())
          .addEnvironment(baseImage.getEnvironment())
          .addLabels(baseImage.getLabels())
          .setHealthCheck(baseImage.getHealthCheck())
          .addExposedPorts(baseImage.getExposedPorts())
          .addVolumes(baseImage.getVolumes())
          .setUser(baseImage.getUser())
          .setWorkingDirectory(baseImage.getWorkingDirectory());

      ContainerConfiguration containerConfiguration = buildContext.getContainerConfiguration();
      // Add history elements for non-empty layers that don't have one yet
      Instant layerCreationTime = containerConfiguration.getCreationTime();
      for (int count = 0; count < baseImageLayers.size() - nonEmptyLayerCount; count++) {
        imageBuilder.addHistory(
            HistoryEntry.builder()
                .setCreationTimestamp(layerCreationTime)
                .setComment("auto-generated by Jib")
                .build());
      }

      // Add built layers/configuration
      for (PreparedLayer applicationLayer : applicationLayers) {
        imageBuilder
            .addLayer(applicationLayer)
            .addHistory(
                HistoryEntry.builder()
                    .setCreationTimestamp(layerCreationTime)
                    .setAuthor("Jib")
                    .setCreatedBy(buildContext.getToolName() + ":" + buildContext.getToolVersion())
                    .setComment(applicationLayer.getName())
                    .build());
      }

      imageBuilder
          .addEnvironment(containerConfiguration.getEnvironmentMap())
          .setCreated(containerConfiguration.getCreationTime())
          .setEntrypoint(computeEntrypoint(baseImage, containerConfiguration))
          .setProgramArguments(computeProgramArguments(baseImage, containerConfiguration))
          .addExposedPorts(containerConfiguration.getExposedPorts())
          .addVolumes(containerConfiguration.getVolumes())
          .addLabels(containerConfiguration.getLabels());
      if (containerConfiguration.getUser() != null) {
        imageBuilder.setUser(containerConfiguration.getUser());
      }
      if (containerConfiguration.getWorkingDirectory() != null) {
        imageBuilder.setWorkingDirectory(containerConfiguration.getWorkingDirectory().toString());
      }

      // Gets the container configuration content descriptor.
      return imageBuilder.build();
    }
  }
@Test
  public void test_propagateBaseImageConfiguration() {
    Mockito.when(mockContainerConfiguration.getEnvironmentMap())
        .thenReturn(ImmutableMap.of("MY_ENV", "MY_ENV_VALUE", "BASE_ENV_2", "NEW_VALUE"));
    Mockito.when(mockContainerConfiguration.getLabels())
        .thenReturn(ImmutableMap.of("my.label", "my.label.value", "base.label.2", "new.value"));
    Mockito.when(mockContainerConfiguration.getExposedPorts())
        .thenReturn(ImmutableSet.of(Port.tcp(3000), Port.udp(4000)));
    Mockito.when(mockContainerConfiguration.getVolumes())
        .thenReturn(
            ImmutableSet.of(
                AbsoluteUnixPath.get("/new/path1"), AbsoluteUnixPath.get("/new/path2")));
    Image image =
        new BuildImageStep(
                mockBuildContext,
                mockProgressEventDispatcherFactory,
                baseImage,
                baseImageLayers,
                applicationLayers)
            .call();
    Assert.assertEquals("wasm", image.getArchitecture());
    Assert.assertEquals("js", image.getOs());
    Assert.assertEquals(
        ImmutableMap.of(
            "BASE_ENV", "BASE_ENV_VALUE", "MY_ENV", "MY_ENV_VALUE", "BASE_ENV_2", "NEW_VALUE"),
        image.getEnvironment());
    Assert.assertEquals(
        ImmutableMap.of(
            "base.label",
            "base.label.value",
            "my.label",
            "my.label.value",
            "base.label.2",
            "new.value"),
        image.getLabels());
    Assert.assertNotNull(image.getHealthCheck());
    Assert.assertEquals(
        ImmutableList.of("CMD-SHELL", "echo hi"), image.getHealthCheck().getCommand());
    Assert.assertTrue(image.getHealthCheck().getInterval().isPresent());
    Assert.assertEquals(Duration.ofSeconds(3), image.getHealthCheck().getInterval().get());
    Assert.assertTrue(image.getHealthCheck().getTimeout().isPresent());
    Assert.assertEquals(Duration.ofSeconds(2), image.getHealthCheck().getTimeout().get());
    Assert.assertTrue(image.getHealthCheck().getStartPeriod().isPresent());
    Assert.assertEquals(Duration.ofSeconds(1), image.getHealthCheck().getStartPeriod().get());
    Assert.assertTrue(image.getHealthCheck().getRetries().isPresent());
    Assert.assertEquals(20, (int) image.getHealthCheck().getRetries().get());
    Assert.assertEquals(
        ImmutableSet.of(Port.tcp(1000), Port.udp(2000), Port.tcp(3000), Port.udp(4000)),
        image.getExposedPorts());
    Assert.assertEquals(
        ImmutableSet.of(
            AbsoluteUnixPath.get("/base/path1"),
            AbsoluteUnixPath.get("/base/path2"),
            AbsoluteUnixPath.get("/new/path1"),
            AbsoluteUnixPath.get("/new/path2")),
        image.getVolumes());
    Assert.assertEquals("/base/working/directory", image.getWorkingDirectory());
    Assert.assertEquals("root", image.getUser());

    Assert.assertEquals(image.getHistory().get(0), nonEmptyLayerHistory);
    Assert.assertEquals(image.getHistory().get(1), emptyLayerHistory);
    Assert.assertEquals(image.getHistory().get(2), emptyLayerHistory);
    Assert.assertEquals(ImmutableList.of(), image.getEntrypoint());
    Assert.assertEquals(ImmutableList.of(), image.getProgramArguments());
  }