func (factory *gardenContainerSpecFactory) BuildContainerSpec(
	spec ContainerSpec,
	resourceTypes []atc.WorkerResourceType,
	cancel <-chan os.Signal,
	delegate ImageFetchingDelegate,
	id Identifier,
	metadata Metadata,
	workerClient Client,
	customTypes atc.ResourceTypes,
) (garden.ContainerSpec, error) {
	var err error

	resourceTypeContainerSpec, ok := spec.(ResourceTypeContainerSpec)
	if ok {
		customType, found := lookupCustomType(resourceTypeContainerSpec.Type, customTypes)
		if found {
			customTypes = customTypes.Without(resourceTypeContainerSpec.Type)

			resourceTypeContainerSpec.ImageResourcePointer = &atc.TaskImageConfig{
				Source: customType.Source,
				Type:   customType.Type,
			}

			spec = resourceTypeContainerSpec
		}
	}

	imageResourceConfig, hasImageResource := spec.ImageResource()
	var gardenSpec garden.ContainerSpec
	if hasImageResource {
		image, err := factory.imageFetcher.FetchImage(
			factory.logger,
			imageResourceConfig,
			cancel,
			id,
			metadata,
			delegate,
			workerClient,
			customTypes,
		)
		if err != nil {
			return garden.ContainerSpec{}, err
		}

		imageVolume := image.Volume()

		factory.volumeHandles = append(factory.volumeHandles, imageVolume.Handle())
		factory.releaseAfterCreate = append(factory.releaseAfterCreate, image)
		factory.user = image.Metadata().User

		gardenSpec = garden.ContainerSpec{
			Properties: garden.Properties{},
			RootFSPath: path.Join(imageVolume.Path(), "rootfs"),
			Env:        image.Metadata().Env,
		}
	} else {
		gardenSpec = garden.ContainerSpec{
			Properties: garden.Properties{},
		}
	}

	switch s := spec.(type) {
	case ResourceTypeContainerSpec:
		gardenSpec, err = factory.BuildResourceContainerSpec(s, gardenSpec, resourceTypes)
	case TaskContainerSpec:
		gardenSpec, err = factory.BuildTaskContainerSpec(s, gardenSpec, cancel, delegate, id, metadata, workerClient)
	default:
		return garden.ContainerSpec{}, fmt.Errorf("unknown container spec type: %T (%#v)", s, s)
	}
	if err != nil {
		return garden.ContainerSpec{}, err
	}

	if len(factory.volumeHandles) > 0 {
		volumesJSON, err := json.Marshal(factory.volumeHandles)
		if err != nil {
			return garden.ContainerSpec{}, err
		}

		gardenSpec.Properties[volumePropertyName] = string(volumesJSON)

		mountsJSON, err := json.Marshal(factory.volumeMounts)
		if err != nil {
			return garden.ContainerSpec{}, err
		}

		gardenSpec.Properties[volumeMountsPropertyName] = string(mountsJSON)
	}

	gardenSpec.Properties["user"] = factory.user

	return gardenSpec, nil
}