class GcpAttachedDiskResourceBuilder extends AbstractGcpComputeBuilder {

    @Override
    public List<CloudResource> build(GcpContext context, long privateId, AuthenticatedContext auth, Group group,
            List<CloudResource> resources, CloudStack cloudStack) throws Exception {
        InstanceTemplate template = group.getReferenceInstanceTemplate();

        List<String> operations = new ArrayList<>();
        List<String> syncedOperations = Collections.synchronizedList(operations);
        String projectId = context.getProjectId();
        Compute compute = context.getCompute();
        Collection<Future<Void>> futures = new ArrayList<>();

        List<CloudResource> buildableResource = resources.stream()
                .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus()))
                .collect(Collectors.toList());

        List<CloudResource> result = new ArrayList<>();
        for (CloudResource volumeSetResource : buildableResource) {
            VolumeSetAttributes volumeSetAttributes = volumeSetResource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class);

            for (VolumeSetAttributes.Volume volume : volumeSetAttributes.getVolumes()) {
                Disk disk = createDisk(projectId, volume, cloudStack.getTags(), volumeSetAttributes);

                gcpDiskEncryptionService.addEncryptionKeyToDisk(template, disk);
                Future<Void> submit = intermediateBuilderExecutor.submit(() -> {
                    Insert insDisk = compute.disks().insert(projectId, volumeSetAttributes.getAvailabilityZone(), disk);
                    try {
                        Operation operation = insDisk.execute();
                        syncedOperations.add(operation.getName());
                        if (operation.getHttpErrorStatusCode() != null) {
                            throw new GcpResourceException(operation.getHttpErrorMessage(), resourceType(), disk.getName());
                        }
                    } catch (GoogleJsonResponseException e) {
                        throw new GcpResourceException(checkException(e), resourceType(), disk.getName());
                    }
                    return null;
                });
                futures.add(submit);
            }
            volumeSetResource.putParameter(OPERATION_ID, operations);
            result.add(new Builder().cloudResource(volumeSetResource)
                    .status(CommonStatus.CREATED)
                    .params(volumeSetResource.getParameters())
                    .build());
        }

        for (Future<Void> future : futures) {
            future.get();
        }

        result.addAll(resources.stream().filter(cloudResource -> CommonStatus.CREATED.equals(cloudResource.getStatus())).collect(Collectors.toList()));
        return result;
    }

}