'Calculate necessary changes to peer-to-peer manifestations.
Datasets that are in use by applications cannot be deleted,
handed-off or resized. See
https://clusterhq.atlassian.net/browse/FLOC-1425 for leases, a
better solution.'

def calculate_changes(self, configuration, cluster_state, local_state):

    local_state = cluster_state.get_node(self.node_uuid)
    phases = []
    local_applications_vector = None
    if local_state.applications:
        local_applications_vector = local_state.applications.values()
    not_in_use_datasets = NotInUseDatasets(node_uuid=self.node_uuid, local_applications=local_applications_vector, leases=configuration.leases)
    dataset_changes = find_dataset_changes(self.node_uuid, cluster_state, configuration)
    resizing = not_in_use_datasets(dataset_changes.resizing)
    if resizing:
        phases.append(in_parallel(changes=[ResizeDataset(dataset=dataset) for dataset in resizing]))
    going = not_in_use_datasets(dataset_changes.going, (lambda d: d.dataset.dataset_id))
    if going:
        phases.append(in_parallel(changes=[HandoffDataset(dataset=handoff.dataset, hostname=handoff.hostname) for handoff in going]))
    if dataset_changes.creating:
        phases.append(in_parallel(changes=[CreateDataset(dataset=dataset) for dataset in dataset_changes.creating]))
    deleting = not_in_use_datasets(dataset_changes.deleting)
    if deleting:
        phases.append(in_parallel(changes=[DeleteDataset(dataset=dataset) for dataset in deleting]))
    return sequentially(changes=phases, sleep_when_empty=timedelta(seconds=1))
