private static Parameter[] LoadParameters(
            IEnumerable <ParameterDTO> parameters,
            Dictionary <string, DataType> typesByName,
            List <string> errors,
            UserProcessDTO process,
            string paramType
            )
        {
            var paramsWithTypes = parameters.Select(
                p => new Tuple <ParameterDTO, DataType>
                (
                    p,
                    typesByName.ContainsKey(p.Type)
                        ? typesByName[p.Type]
                        : null
                )
                ).ToArray();

            var errorParams = paramsWithTypes
                              .Where(i => i.Item2 == null)
                              .Select(i => i.Item1);

            foreach (var param in errorParams)
            {
                errors.Add($"Unrecognised type \"{param.Type}\" used by {paramType} of process {process.Name}");
            }

            return(paramsWithTypes
                   .Select(i => new Parameter(i.Item1.Name, i.Item2))
                   .ToArray());
        }
        private static List <Variable> LoadVariables(UserProcessDTO process, Dictionary <string, DataType> typesByName, List <string> errors)
        {
            var variables = new List <Variable>();

            var usedNames = new HashSet <string>();

            foreach (var variableData in process.Variables)
            {
                if (usedNames.Contains(variableData.Name))
                {
                    errors.Add($"Multiple variables of process {process.Name} use the same name: {variableData.Name}");
                    continue;
                }

                usedNames.Add(variableData.Name);

                if (!typesByName.TryGetValue(variableData.Type, out DataType dataType))
                {
                    errors.Add($"Unrecognised type \"{variableData.Type}\" used by variable {variableData.Name} of process {process.Name}");
                    continue;
                }

                var value = variableData.InitialValue != null && dataType is IDeserializable
                    ? (dataType as IDeserializable).Deserialize(variableData.InitialValue)
                    : dataType.GetDefaultValue();

                variables.Add(new Variable(variableData.Name, dataType, value));
            }

            return(variables);
        }
        private static UserProcess CreateProcess(UserProcessDTO processData, Dictionary <string, DataType> typesByName, List <string> errors)
        {
            var inputs = LoadParameters(processData.Inputs, typesByName, errors, processData, "input");

            var outputs = LoadParameters(processData.Outputs, typesByName, errors, processData, "output");

            var variables = LoadVariables(processData, typesByName, errors);

            return(new UserProcess
                   (
                       processData.Name,
                       processData.Description,
                       inputs,
                       outputs,
                       processData.ReturnPaths,
                       variables
                   ));
        }