private void SetFileComplete(string processResultMessage, Guid destinationRefId)
        {
            bool resultStatus = true; //assume good result

            TransferMainService transferMainService = new TransferMainService();
            TransferWorkService transferWorkService = new TransferWorkService();
            TransferMain tm;
            TList<TransferWork> twList = null;

            // Look up transfer record by ID
            tm = transferMainService.GetByTransferRefId(mWorkRefId);
            bool usesWorkRecords = tm.TransferTypeId == (short)TransferTypeList.FileWatchAndProcess ? false : true;

            try
            {
                LogManager.GetLogger("SiteLogger").Debug("SetFileComplete(): started on " + mWorkItem);
                //logger.logEntry(this.ToString(), "SetFileComplete(): started on " + mWorkItem, LogMsgSeverity.Trace, false);

                if (usesWorkRecords)
                {
                    // check to see if all the transfers are done
                    TransferWork tw = transferWorkService.GetByTransferRefIdDestinationRefId(tm.TransferRefId, destinationRefId);

                    if (tw == null)
                        throw new SystemException("Unable to find transfer records for destination " + destinationRefId);

                    twList = transferWorkService.GetByTransferRefId(tm.TransferRefId);

                    if (twList.Count == 0)
                        throw new SystemException(this.ToString() + ":Unable to find transfer records for workId " + mWorkRefId);

                    foreach (TransferWork tw1 in twList)
                    {
                        if (tw1.StatusTypeId == (short)StatusTypeList.Pending)
                            return; // we have arecord that's not finished
                        if (tw1.StatusTypeId == (short)StatusTypeList.Error)
                            resultStatus = false; // we have a failed record
                    }
                }

                if (tm.UsePendingFileStucture)
                {
                    if (usesWorkRecords)
                    {
                        foreach (TransferWork tw1 in twList)
                        {
                            if (tw1.Filename.IndexOf("*") >= 0 || tw1.Filename.IndexOf("?") >= 0)
                            {
                                DirectoryInfo di = new DirectoryInfo(tm.WatchDir);
                                FileInfo[] fis = di.GetFiles();
                                foreach (FileInfo fi in fis)
                                {
                                    if (tm.TransferTypeId < 3)
                                        CleanUpRunFiles(usesWorkRecords, resultStatus, fi.FullName, twList);
                                }
                            }
                            else
                            {
                                if (tm.TransferTypeId < 3)
                                    CleanUpRunFiles(usesWorkRecords, resultStatus, tw1.Filename, twList);
                            }

                            tw1.MarkToDelete();

                            LogManager.GetLogger("SiteLogger").Debug("SetFileComplete(): ended on " + mWorkItem);
                            //logger.logEntry(this.ToString(), "SetFileComplete(): ended on " + mWorkItem, LogMsgSeverity.Trace, false);
                        }

                        transferWorkService.Save(twList);
                    }
                    else
                    {
                        if (tm.TransferTypeId < 3)
                            CleanUpRunFiles(usesWorkRecords, resultStatus, mWorkItem, twList);

                        LogManager.GetLogger("SiteLogger").Debug("SetFileComplete(): ended on " + mWorkItem);
                        //logger.logEntry(this.ToString(), "SetFileComplete(): ended on " + mWorkItem, LogMsgSeverity.Trace, false);
                    }
                }
                else
                {
                    foreach (TransferWork tw1 in twList)
                    {
                        tw1.MarkToDelete();
                    }

                    transferWorkService.Save(twList);

                    // not always going to be there
                    try
                    {
                        //delete in file
                        FileInfo inFile = new FileInfo(mWorkItem);
                        inFile.IsReadOnly = false;
                        inFile.Delete();
                    }
                    catch (Exception)
                    {
                    }
                }

            }
            catch (Exception ex)
            {
                LogManager.GetLogger("SiteLogger").Debug("SetFileComplete(): Failed.", ex);
                //logger.logEntry(this.ToString(), "SetFileComplete(): Failed." + ex.Message, LogMsgSeverity.Critical, false);
            }
        }
        public void WorkerLoop()
        {
            try
            {

                // do work
                LogManager.GetLogger("SiteLogger").Info("Working on " + mWorkItem);
                //logger.logEntry(this.ToString(), "Working on " + mWorkItem, LogMsgSeverity.Information, false);

                //TODO: Write the data to the work table to support restarts
                //FileTransferService.TransferWorkDataHandler twdh = new FileTransferService.TransferWorkDataHandler();
                //FileTransferService.TransferWorkDS twDS = new FileTransferService.TransferWorkDS();
                //twDS.TransferWork.AddTransferWorkRow(0,
                //twdh.SetTransferWork(

                try
                {

                    TransferMainService transferMainService = new TransferMainService();

                    DestinationService destinationsService = new DestinationService();

                    TransferWorkService transferWorkService = new TransferWorkService();

                    FTPProcessor ifpx;
                    DoFTPActionStartDelegate dlgt;
                    IAsyncResult ar;

                    // Look up transfer record by ID
                    TransferMain tm = transferMainService.GetByTransferRefId(mWorkRefId);

                    mTransferType = (TransferTypeList)tm.TransferTypeId;

                    // check to make sure the file is complete
                    if (mTransferType == TransferTypeList.FileWatchAndProcess)
                    {
                        while (!TryToOpenInExclusiveMode(mWorkItem))
                        {
                            System.Threading.Thread.Sleep(5000);
                        }
                    }

                    // Look up transfer record by ID
                    TList<Destination> dests = destinationsService.GetByTransferRefId(mWorkRefId);

                    switch (mTransferType)
                    {
                        case TransferTypeList.FileWatchAndProcess:
                            if (tm.UsePendingFileStucture)
                                SetFilePending();

                            // Create the delegate.
                            //MDBInterfaceProcessor mdbip = new MDBInterfaceProcessor();
                            //mdbip.ProcessFileComplete += new ProcessFileCompleteDelegate(OnProcessFileComplete);

                            bool processResult;
                            ProcessTypeService pts = new ProcessTypeService();
                            ProcessType pt = pts.GetByProcessTypeId((short)tm.ProcessTypeId);

                            string path = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;

                            this.ExecuteProcessorAssemblyMethod(mWorkItem, (short)tm.ProcessTypeId, out processResult, System.IO.Path.Combine(path, pt.LoadAssembly), pt.ClassName);
                            //mdbip.ProcessFile(mWorkItem,  (InterfaceType)ip.ProcessTypeId , out processResult);
                            break;

                        case TransferTypeList.FileWatchFtpPut:
                            if (tm.UsePendingFileStucture)
                                SetFilePending();

                            // fire a transfer for every destination you find
                            foreach (Destination dest in dests)
                            {
                                // Create the delegate.
                                ifpx = new FTPProcessor();
                                dlgt = new DoFTPActionStartDelegate(ifpx.DoFTPAction);

                                /// write transfer to work table
                                TransferWork transferWork = new TransferWork();
                                transferWork.TransferWorkRefId = Guid.NewGuid();
                                transferWork.TransferRefId = dest.TransferRefId;
                                transferWork.DestinationRefId = dest.DestinationRefId;
                                transferWork.Filename = mWorkItem;
                                transferWork.SubmitTime = DateTime.Now;
                                //transferWork.CompletionTime = DateTime.MinValue;
                                transferWork.Retires = 0;
                                transferWork.StatusTypeId = (short)StatusTypeList.New;

                                transferWorkService.Save(transferWork);

                                // Initiate the asychronous call.  Include an AsyncCallback
                                // delegate representing the callback method, and the data
                                // needed to call EndInvoke.
                                //TODO: Make this a generic call back function
                                ar = dlgt.BeginInvoke(new FTPEventArgs(dest.DestinationRefId, dest.DestServer, dest.SourceDir, dest.DestDir, dest.Username, dest.Password,
                                                        true, FtpClient.TransferType.PUT, mWorkItem, dest.DeleteAfterProcessing, ftpRetryThreshhold),
                                                        out processResult, out destinationRefId, new AsyncCallback(OnFTPActionComplete), dlgt);

                            }

                            break;

                        case TransferTypeList.FileWatchFtpPutGet:
                            break;

                        case TransferTypeList.FtpGet:
                            if (tm.UsePendingFileStucture)
                            {
                                FileInfo file = new FileInfo(mWorkItem);
                                if (!file.Exists)
                                    file.Create(); // used for gets

                                SetFilePending();
                            }

                            foreach (Destination dest in dests)
                            {
                                // Create the delegate.
                                ifpx = new FTPProcessor();
                                dlgt = new DoFTPActionStartDelegate(ifpx.DoFTPAction);

                                /// write transfer to work table
                                TransferWork transferWork = new TransferWork();
                                transferWork.TransferWorkRefId = Guid.NewGuid();
                                transferWork.TransferRefId = dest.TransferRefId;
                                transferWork.DestinationRefId = dest.DestinationRefId;
                                transferWork.Filename = mWorkItem;
                                transferWork.SubmitTime = DateTime.Now;
                                transferWork.Retires = 0;
                                transferWork.StatusTypeId = (short)StatusTypeList.New;

                                try
                                {
                                    transferWorkService.Save(transferWork);
                                }
                                catch (System.Data.SqlClient.SqlException ex)
                                {
                                    LogManager.GetLogger("SiteLogger").Warn("Error Saving Transfer work on " + mWorkItem,ex);
                                    //logger.logEntry(this.ToString(), "Error Saving Transfer work on " + mWorkItem + " " + ex.Message, LogMsgSeverity.Warning, false);
                                }

                                // Initiate the asychronous call.  Include an AsyncCallback
                                // delegate representing the callback method, and the data
                                // needed to call EndInvoke.
                                //TODO: Make this a generic call back function
                                ar = dlgt.BeginInvoke(new FTPEventArgs(dest.DestinationRefId, dest.SourceServer, dest.DestDir, dest.SourceDir, dest.Username, dest.Password,
                                                                        true, FtpClient.TransferType.GET, mWorkItem, dest.DeleteAfterProcessing,
                                                                        ftpRetryThreshhold), out processResult, out destinationRefId, new AsyncCallback(OnFTPActionComplete), dlgt);

                            }

                            break;

                        case TransferTypeList.FtpGetPut:
                            break;
                    }

                    LogManager.GetLogger("SiteLogger").Debug("Async WorkerLoop(): Started.");
                    //logger.logEntry(this.ToString(), "Async WorkerLoop(): Started.", LogMsgSeverity.Trace, false);

                    // sleep for 5 sec then check result
                    Thread.Sleep(5000);

                    LogManager.GetLogger("SiteLogger").Debug("Async WorkerLoop(): Ended.");
                    //logger.logEntry(this.ToString(), "Async WorkerLoop(): Ended.", LogMsgSeverity.Trace, false);

                }
                catch (Exception ex)
                {
                    LogManager.GetLogger("SiteLogger").Fatal("Async WorkerLoop(): Failed.", ex);
                    //logger.logEntry(this.ToString(), "Async WorkerLoop(): Failed." + ex.Message, LogMsgSeverity.Critical, false);
                }

            }
            catch (Exception ex)
            {
                LogManager.GetLogger("SiteLogger").Fatal("Async WorkerLoop(): Failed.", ex);
                //logger.logEntry(this.ToString(), "Async WorkerLoop(): Failed." + ex.Message, LogMsgSeverity.Critical, false);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ar"></param>
        private void OnFTPActionComplete(IAsyncResult ar)
        {
            string processResultMessage = "";
            try
            {
                // Retrieve the delegate.
                DoFTPActionStartDelegate dlgt = (DoFTPActionStartDelegate)ar.AsyncState;

                TransferMainService transferMainService = new TransferMainService();

                TransferWorkService transferWorkService = new TransferWorkService();

                // Look up transfer record by ID
                TransferMain tm = transferMainService.GetByTransferRefId(mWorkRefId);

                lock (this)
                {

                    // Call EndInvoke to retrieve the results.
                    processResultMessage = dlgt.EndInvoke(out processResult, out destinationRefId, ar);

                    // display or process aync results
                    LogManager.GetLogger("SiteLogger").Info("Processing Complete: " + processResult + " with result: " + processResultMessage);
                    //logger.logEntry(this.ToString(), "Processing Complete: " + processResult + " with result: " + processResultMessage, LogMsgSeverity.Information, false);

                    // update transfer record
                    /// write transfer to work table

                    TransferWork tw = transferWorkService.GetByTransferRefIdDestinationRefId(tm.TransferRefId, destinationRefId);

                    if (tw == null)
                        throw new SystemException("Unable to find transfer records for destination " + destinationRefId);

                    tw.CompletionTime = DateTime.Now;

                    if (processResult)
                        tw.StatusTypeId = (short)StatusTypeList.Complete;
                    else
                    {
                        tw.StatusTypeId = (short)StatusTypeList.Error;
                        // reset the schedule to run in 2 hours on an error
                        EventScheduler eventScheduler = new EventScheduler();
                        eventScheduler.GetSchedule((Guid)tm.ScheduleRefId).NextInvokeTime = DateTime.Now.AddHours(2);
                    }

                    tw.Retires += 1;
                    if (tw.Results == null)
                        tw.Results = processResultMessage + "\n";
                    else
                        tw.Results += processResultMessage + "\n";

                    transferWorkService.Save(tw);

                    //TODO: figure this out
                    //clean things up
                    SetFileComplete(processResultMessage, destinationRefId);
                }

            }
            catch (Exception ex)
            {
                LogManager.GetLogger("SiteLogger").Fatal("Callback method  DoFTPActionComplete(): Failed.", ex);
                //logger.logEntry(this.ToString(), "Callback method  DoFTPActionComplete(): Failed." + ex.Message, LogMsgSeverity.Critical, false);
            }
        }