/// <summary>
 /// Restore process state from a DataObject (obtained by calling SaveProcessState).
 /// This is the preferred way of storing process state in NGinn. Of course
 /// process instance can be binary serialized and saved, but the binary format
 /// causes problems when upgrading class versions.
 /// </summary>
 /// <param name="dob"></param>
 public void RestoreState(DataObject dob)
 {
     if (this._activated) throw new ApplicationException("Restore is not possible after activation");
     string v = (string) dob["APIVersion"];
     if (!APIVERSION.Equals(v))
     {
         log.Warn("Trying to restore process state from version {0}. API version is {1}", v, APIVERSION);
     }
     _instId = (string) dob["InstanceId"];
     _definitionId = (string) dob["ProcessDefinitionId"];
     _status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), (string) dob["Status"]);
     _persistedVersion = Convert.ToInt32(dob["PersistedVersion"]);
     _processInstanceData = (DataObject) dob["InstanceData"];
     _correlationId = (string)dob["CorrelationId"];
     _tokenNumber = Convert.ToInt32(dob["TokenNumber"]);
     _transitionNumber = Convert.ToInt32(dob["TransitionNumber"]);
     IList l = dob.GetArray("Token");
     _tokens = new Dictionary<string, Token>();
     if (l != null)
     {
         foreach (DataObject dob2 in l)
         {
             Token tok = new Token();
             tok.RestoreState(dob2);
             _tokens[tok.TokenId] = tok;
         }
     }
     _activeTransitions = new Dictionary<string, TaskShell>();
     l = dob.GetArray("Transition");
     if (l != null)
     {
         foreach (DataObject dob2 in l)
         {
             TaskShell ts = TaskShell.RestoreTaskShell(dob2);
             _activeTransitions[ts.CorrelationId] = ts;
         }
     }
     foreach (Token tok in _tokens.Values)
     {
         if (tok.Status != TokenStatus.CONSUMED &&
             tok.Status != TokenStatus.CANCELLED)
         {
             foreach (string atid in tok.ActiveTransitions)
             {
                 if (!_activeTransitions.ContainsKey(atid)) throw new Exception("Invalid transition id: " + atid);
             }
         }
     }
     foreach (TaskShell ts in _activeTransitions.Values)
     {
         if (ts.Status == TransitionStatus.ENABLED ||
             ts.Status == TransitionStatus.STARTED)
         {
             foreach (string tokid in ts.Tokens)
             {
                 if (!_tokens.ContainsKey(tokid)) throw new Exception("Invalid token: " + tokid);
             }
         }
     }
 }