# Path: ncdjango/geoprocessing/params.py
# class ParameterCollection(object):
#     """Manages a collection of parameter types and values"""
# 
#     def __init__(self, parameters):
#         """
#         :param parameters: A list of `Parameter` objects
#         """
# 
#         self.parameters = parameters
#         self.by_name = {p.name: p for p in self.parameters}
#         self.values = {}
# 
#     def __setitem__(self, key, value):
#         self.values[key] = self.by_name[key].clean(value)
# 
#     def __getitem__(self, item):
#         return self.values.get(item)
# 
#     @property
#     def is_complete(self):
#         """Do all required parameters have values?"""
# 
#         return all(p.name in self.values for p in self.parameters if p.required)
# 
#     def format_args(self):
#         """Returns dictionary containing values for all named parameters."""
# 
#         return self.values
# 
# class Parameter(metaclass=ParameterBase):
#     """
#     Base parameter (input, output, or uniform) class for a task or workflow. Extended to implement specific parameter
#     types.
#     """
# 
#     id = None  # A unique name for this parameter, used for serialization
# 
#     def __init__(self, name, required=True):
#         """
#         :param name: The parameter name. This will be used as a keyword argument to the task's `execute()` method.
#         :param required: When True, input validation will fail if no value is provided.
#         """
# 
#         self.name = name
#         self.required = required
# 
#     @classmethod
#     def by_id(cls, param_id):
#         return cls._parameters_by_id.get(param_id)
# 
#     def clean(self, value):
#         """Cleans and returns the given value, or raises a ParameterNotValidError exception"""
# 
#         return value
# 
#     def serialize_args(self):
#         """Returns (args, kwargs) to be used when deserializing this parameter."""
# 
#         return (self.name,), {'required': True}
# 
#     @staticmethod
#     def deserialize_args(args, kwargs):
#         """Returns deserialized forms of (args, kwargs) to be used when re-constructing this parameter."""
# 
#         return args, kwargs


import copy
import json
import logging
import time
from .params import ParameterCollection, Parameter
        if node_id in self.nodes_by_id:
            raise ValueError('The node {0} already exists in this workflow.'.format(node_id))

        node = WorkflowNode(node_id, task, inputs)
        self.nodes_by_id[node_id] = node

        for source, value in inputs.values():
            if source == 'dependency':
                dependents = self.dependents_by_node_id.get(value[0], set())
                dependents.add(node_id)
                self.dependents_by_node_id[value[0]] = dependents

    def map_output(self, node_id, node_output_name, parameter_name):
        """
        Maps the output from a node to a workflow output.

        :param node_id: The id of the node to map from.
        :param node_output_name: The output parameter name for the node task to map to the workflow output.
        :param parameter_name: The workflow output parameter name.
        """

        self.output_mapping[parameter_name] = (node_id, node_output_name)

        dependents = self.dependents_by_node_id.get(node_id, set())
        dependents.add('output_{}'.format(parameter_name))
        self.dependents_by_node_id[node_id] = dependents

    def to_json(self, indent=None):
        """Serialize this workflow to JSON"""


# Path: ncdjango/geoprocessing/params.py
# class ParameterCollection(object):
#     """Manages a collection of parameter types and values"""
# 
#     def __init__(self, parameters):
#         """
#         :param parameters: A list of `Parameter` objects
#         """
# 
#         self.parameters = parameters
#         self.by_name = {p.name: p for p in self.parameters}
#         self.values = {}
# 
#     def __setitem__(self, key, value):
#         self.values[key] = self.by_name[key].clean(value)
# 
#     def __getitem__(self, item):
#         return self.values.get(item)
# 
#     @property
#     def is_complete(self):
#         """Do all required parameters have values?"""
# 
#         return all(p.name in self.values for p in self.parameters if p.required)
# 
#     def format_args(self):
#         """Returns dictionary containing values for all named parameters."""
# 
#         return self.values
# 
# class Parameter(metaclass=ParameterBase):
#     """
#     Base parameter (input, output, or uniform) class for a task or workflow. Extended to implement specific parameter
#     types.
#     """
# 
#     id = None  # A unique name for this parameter, used for serialization
# 
#     def __init__(self, name, required=True):
#         """
#         :param name: The parameter name. This will be used as a keyword argument to the task's `execute()` method.
#         :param required: When True, input validation will fail if no value is provided.
#         """
# 
#         self.name = name
#         self.required = required
# 
#     @classmethod
#     def by_id(cls, param_id):
#         return cls._parameters_by_id.get(param_id)
# 
#     def clean(self, value):
#         """Cleans and returns the given value, or raises a ParameterNotValidError exception"""
# 
#         return value
# 
#     def serialize_args(self):
#         """Returns (args, kwargs) to be used when deserializing this parameter."""
# 
#         return (self.name,), {'required': True}
# 
#     @staticmethod
#     def deserialize_args(args, kwargs):
#         """Returns deserialized forms of (args, kwargs) to be used when re-constructing this parameter."""
# 
#         return args, kwargs


# Path: ncdjango/geoprocessing/workflow.py
import copy
import json
import logging
import time
from .params import ParameterCollection, Parameter

        if node_id in self.nodes_by_id:
            raise ValueError('The node {0} already exists in this workflow.'.format(node_id))

        node = WorkflowNode(node_id, task, inputs)
        self.nodes_by_id[node_id] = node

        for source, value in inputs.values():
            if source == 'dependency':
                dependents = self.dependents_by_node_id.get(value[0], set())
                dependents.add(node_id)
                self.dependents_by_node_id[value[0]] = dependents

    def map_output(self, node_id, node_output_name, parameter_name):
        """
        Maps the output from a node to a workflow output.

        :param node_id: The id of the node to map from.
        :param node_output_name: The output parameter name for the node task to map to the workflow output.
        :param parameter_name: The workflow output parameter name.
        """

        self.output_mapping[parameter_name] = (node_id, node_output_name)

        dependents = self.dependents_by_node_id.get(node_id, set())
        dependents.add('output_{}'.format(parameter_name))
        self.dependents_by_node_id[node_id] = dependents

    def to_json(self, indent=None):
        """Serialize this workflow to JSON"""


        inputs = ParameterCollection(self.inputs)