//======================================================
        //      Public methods
        //======================================================
        /// <summary>
        /// Instanciates a new process step from a deserialized description.
        /// </summary>
        /// <param name="data">The data describing the process step.</param>
        /// <returns>The instanciated process step, or null if an error occured.</returns>
        public static ProcessStep Instanciate(ProcessStepInstanceData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            // Check the runtime type for validity
            var definition  = data?.Definition;
            var runtimeType = definition?.RuntimeType;

            if (runtimeType == null)
            {
                return(null);
            }

            // Try instanciating an instance of the runtime state
            ProcessStep step = null;

            try
            {
                step = Activator.CreateInstance(runtimeType) as ProcessStep;
            }
            catch
            {
                return(null);
            }

            // Set the parameters
            step.Id         = data.Id;
            step.Definition = definition;
            foreach (var parameterKvp in data.ParameterValues)
            {
                try
                {
                    Util.SetMemberValue(step, parameterKvp.Key, parameterKvp.Value);
                }
                catch { }
            }

            return(step);
        }
        /// <summary>
        /// Instanciates a new transport process which implements the logic described in a deserialized instance description.
        /// </summary>
        /// <param name="data">The deserialized transport process instance description.</param>
        /// <returns>The instanciated transport process, or null if an error occured.</returns>
        public static TransportProcess Instanciate(ProcessInstanceData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var result = new TransportProcess();

            // Construct states
            foreach (var stepData in data.Steps)
            {
                // Construct the state
                var step = ProcessStep.Instanciate(stepData);

                // Add the step to the automaton
                result.Add(step);
            }

            // Construct edges
            foreach (var edgeData in data.Edges)
            {
                Edge edge = new Edge
                {
                    Source      = result.Steps.FirstOrDefault(s => s.Id == edgeData.SourceId),
                    Destination = result.Steps.FirstOrDefault(s => s.Id == edgeData.DestinationId)
                };
                edge.SourceExit = edge.Source?.Definition?.Exits.FirstOrDefault(e => e.Name == edgeData.SourceExit);

                result.Add(edge);
            }

            // Set initial state
            result.InitialState = result.Steps.FirstOrDefault(s => s.Id == data.InitialStateId);

            return(result);
        }