상속: IDisposable
        public static string GetProcessDataFieldValue(string K2Server, int processInstanceID, string dataFieldName)
        {
            //TODO: this currently opens a connection to wf server twice
            using (K2Helper helper = new K2Helper(K2Server))
            {
                Dictionary<string, object> Data = new Dictionary<string, object>();
                Data.Add("ProcessInstanceID", processInstanceID);
                Data.Add("DataName", dataFieldName);
                //////////Data.Add("ProcessName", "Underwriting\\Supplementary\\Setup");



                DataTable dt = helper.SmartObjectClient().SmartObjectGetList(Data, "Process_Data", "List", true);

                foreach (DataRow dr in dt.Rows)
                {
                    return dr.Field<string>("DataValue");
                }
                throw new Exception(string.Format("Cannot find datafield {0} for PI: {1}", dataFieldName, processInstanceID));
            }
        }
 public static string GetActivityStatus(string K2Server ,int processInstanceID, string activityName)
 {
     using (K2Helper helper = new K2Helper(K2Server))
     {
         Dictionary<string, object> Data = new Dictionary<string, object>();
         Data.Add("ProcessInstanceID", processInstanceID.ToString());
         Data.Add("ActivityName", activityName);
         DataTable dt = helper.SmartObjectClient().SmartObjectGetList(Data, "Activity_Instance", "List");
         
         DateTime latestTime = DateTime.MinValue;
         string lastestAndGreatestStatus = string.Empty;
         foreach (DataRow dr in dt.Rows)
         {
             DateTime currentTime = dr.Field<DateTime>("StartDate");
             if (currentTime > latestTime)
             {
                 lastestAndGreatestStatus = dr.Field<string>("Status");
                 latestTime = currentTime;
             }
         }
         return lastestAndGreatestStatus; //empty string if not found
     }
 }
        /// <summary>
        /// ASSUMPTION: IPCs have the same (otherwise unique) folio as their parents 
        /// - not always the case, but no other way of detecting IPC
        /// This uses the parent Process instance ID to get the folio
        /// We then get a list of processes with that folio and exclude the parent.
        /// </summary>
        /// <param name="ParentProcessInstanceID">pid of the parent</param>
        /// <returns>-1 if ipc child is not found, otherwise the processinstanceid</returns>
        public static int GetIPCProcessInstanceByFolio(string K2Server, int ParentProcessInstanceID, string ProcessFullName)
        {
            using (K2Helper helper = new K2Helper(K2Server))
            {

                string processFolder;
                string processName;
                SplitPathIntoFolderAndName(ProcessFullName, out processFolder, out processName);

                Dictionary<string, object> Data = new Dictionary<string, object>();
                Data.Add("ProcessInstanceID", ParentProcessInstanceID.ToString());
                DataTable dt = helper.SmartObjectClient().SmartObjectGetList(Data, "Process_Instance", "List");
                if (dt.Rows.Count == 0)
                {
                    return (int)ReturnCodes.NoProcessInstanceFound;
                }
                else
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        string folio = dr.Field<string>("Folio");
                        Data = new Dictionary<string, object>();
                        Data.Add("Folio", folio); //where for art thou folio?
                        Data.Add("ProcessName", processName);
                        Data.Add("Folder", processFolder);

                        dt = helper.SmartObjectClient().SmartObjectGetList(Data, "Process_Instance", "List");
                        if (dt.Rows.Count == 0)
                        {
                            return (int)ReturnCodes.NoProcessInstanceFound;
                        }
                        else
                        {
                            foreach (DataRow row in dt.Rows)
                            {
                                if (row.Field<int>("ProcessInstanceID") != ParentProcessInstanceID)
                                {
                                    return row.Field<int>("ProcessInstanceID");
                                }
                            }
                            return (int)ReturnCodes.NoProcessInstanceFound;
                        }
                    }

                    return (int)ReturnCodes.NoProcessInstanceFound;
                }
            }
        }
        public void StartTest(string k2server)
        {
            K2Server = k2server;
            SendResult(new TestResultArgs(null, null, TestResultStage.TestEngineStarted, "Please wait for test to start..."));
            try
            {
                k2helper = new K2Helper(K2Server);
                if (XMLLoaded)
                {
                    StartProcessTesting();
                }
                else
                {
                    //Don't throw, error reported to screen
                    //throw new Exception("XML Test file not loaded");
                }
            }//leeeeeeeeeeeee
            catch (Exception ex)
            {
                if (ex.IsFatal())
                {
                    throw;
                }
                SendResult(new TestResultArgs(null, null, TestResultStage.FatalError, ex.Message + ex.StackTrace));
                return;
            }
            finally
            {
                if (k2helper != null)
                {
                    k2helper.Dispose();
                }
            }

        }
        private void recordFileStructure(string childFilename, string parentFilename)
        {
            if (this.RecordStructure)
            {
                childFilename = childFilename.Replace(this.XmlFilesParentDirectory + "\\", string.Empty);
                parentFilename = parentFilename.Replace(this.XmlFilesParentDirectory + "\\", string.Empty);
                Console.WriteLine(childFilename);
                Console.WriteLine(parentFilename);
                var inputFields = new Dictionary<string, object>();
                inputFields.Add("Filename", childFilename);

                using (K2Helper helper = new K2Helper(K2Server))
                {
                    helper.SmartObjectClient().SMOClient.CallSmartObjectExecuteMethod("Filename", "Save", inputFields);
                    if (parentFilename.Length != 0)
                    {
                        inputFields = new Dictionary<string, object>();

                        inputFields.Add("ParentFilename", parentFilename);
                        inputFields.Add("ChildFilename", childFilename);

                        helper.SmartObjectClient().SMOClient.CallSmartObjectExecuteMethod("FilenameRelationship", "Save", inputFields);
                    }
                }
            }
        }