It("returns all added Amis", func() {
		amiCollection := collection.Ami{}

		fakeAmis := []resources.Ami{
			resources.Ami{
				ID:     "fake-0",
				Region: "fake-region-0",
			},
			resources.Ami{
				ID:     "fake-1",
				Region: "fake-region-1",
			},
		}

		for _, fakeAmi := range fakeAmis {
			amiCollection.Add(fakeAmi)
		}

		Expect(amiCollection.GetAll()).To(Equal(fakeAmis))
	})

	It("merges another collection into itself", func() {
		collectionA := &collection.Ami{}
		collectionB := &collection.Ami{}

		fakeAmis := []resources.Ami{
			resources.Ami{
				ID:     "fake-0",
				Region: "fake-region-0",
			},
			resources.Ami{
func (p *StandardRegionPublisher) Publish(ds driverset.StandardRegionDriverSet, machineImageConfig MachineImageConfig) (*collection.Ami, error) {

	createStartTime := time.Now()
	defer func(startTime time.Time) {
		p.logger.Printf("completed Publish() in %f minutes\n", time.Since(startTime).Minutes())
	}(createStartTime)

	machineImageDriverConfig := resources.MachineImageDriverConfig{
		MachineImagePath: machineImageConfig.LocalPath,
		FileFormat:       machineImageConfig.FileFormat,
		BucketName:       p.BucketName,
	}

	machineImageDriver := ds.MachineImageDriver()
	machineImage, err := machineImageDriver.Create(machineImageDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating machine image: %s", err)
	}
	defer func() {
		err := machineImageDriver.Delete(machineImage)
		if err != nil {
			p.logger.Printf("Failed to delete machine image %s: %s", machineImage.GetURL, err)
		}
	}()

	snapshotDriverConfig := resources.SnapshotDriverConfig{
		MachineImageURL: machineImage.GetURL,
		FileFormat:      machineImageConfig.FileFormat,
	}

	snapshotDriver := ds.CreateSnapshotDriver()
	snapshot, err := snapshotDriver.Create(snapshotDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating snapshot: %s", err)
	}

	createAmiDriver := ds.CreateAmiDriver()
	createAmiDriverConfig := resources.AmiDriverConfig{
		SnapshotID:    snapshot.ID,
		AmiProperties: p.AmiProperties,
	}

	sourceAmi, err := createAmiDriver.Create(createAmiDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating ami: %s", err)
	}

	amis := collection.Ami{
		VirtualizationType: p.AmiProperties.VirtualizationType,
	}
	amis.Add(sourceAmi)

	copyAmiDriver := ds.CopyAmiDriver()

	procGroup := sync.WaitGroup{}
	procGroup.Add(len(p.CopyDestinations))

	errCol := collection.Error{}

	for i := range p.CopyDestinations {
		go func(dstRegion string) {
			defer procGroup.Done()

			copyAmiDriverConfig := resources.AmiDriverConfig{
				ExistingAmiID:     sourceAmi.ID,
				DestinationRegion: dstRegion,
				AmiProperties:     p.AmiProperties,
			}

			copiedAmi, copyErr := copyAmiDriver.Create(copyAmiDriverConfig)
			if copyErr != nil {
				errCol.Add(fmt.Errorf("copying source ami: %s to destination region: %s: %s", sourceAmi.ID, dstRegion, copyErr))
				return
			}

			amis.Add(copiedAmi)
		}(p.CopyDestinations[i])
	}

	procGroup.Wait()

	return &amis, errCol.Error()
}
func (p *IsolatedRegionPublisher) Publish(ds driverset.IsolatedRegionDriverSet, machineImageConfig MachineImageConfig) (*collection.Ami, error) {
	createStartTime := time.Now()
	defer func(startTime time.Time) {
		p.logger.Printf("completed Publish() in %f minutes\n", time.Since(startTime).Minutes())
	}(createStartTime)

	machineImageDriverConfig := resources.MachineImageDriverConfig{
		MachineImagePath: machineImageConfig.LocalPath,
		BucketName:       p.BucketName,
		FileFormat:       machineImageConfig.FileFormat,
		VolumeSizeGB:     machineImageConfig.VolumeSizeGB,
	}

	machineImageDriver := ds.MachineImageDriver()
	machineImage, err := machineImageDriver.Create(machineImageDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating machine image: %s", err)
	}

	defer func() {
		err := machineImageDriver.Delete(machineImage)
		if err != nil {
			p.logger.Printf("Failed to delete machine image %s: %s", machineImage.GetURL, err)
		}
	}()

	volumeDriverConfig := resources.VolumeDriverConfig{
		MachineImageManifestURL: machineImage.GetURL,
	}

	volumeDriver := ds.VolumeDriver()
	volume, err := volumeDriver.Create(volumeDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating volume: %s", err)
	}

	defer func() {
		err := volumeDriver.Delete(volume)
		if err != nil {
			p.logger.Printf("Failed to delete volume %s: %s", volume.ID, err)
		}
	}()

	snapshotDriverConfig := resources.SnapshotDriverConfig{
		VolumeID: volume.ID,
	}

	snapshotDriver := ds.CreateSnapshotDriver()
	snapshot, err := snapshotDriver.Create(snapshotDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating snapshot: %s", err)
	}

	createAmiDriver := ds.CreateAmiDriver()
	createAmiDriverConfig := resources.AmiDriverConfig{
		SnapshotID:    snapshot.ID,
		AmiProperties: p.AmiProperties,
	}

	sourceAmi, err := createAmiDriver.Create(createAmiDriverConfig)
	if err != nil {
		return nil, fmt.Errorf("creating ami: %s", err)
	}

	amis := collection.Ami{
		VirtualizationType: p.AmiProperties.VirtualizationType,
	}
	amis.Add(sourceAmi)

	// TODO: cleanup machine images and volumes

	return &amis, nil
}