private void Process(DicomMessageBase message, FileImportBehaviourEnum fileImportBehaviour, WorkItem workItem, DicomProcessingResult result)
        {
            result.Initialize();

            // Use the command processor for rollback capabilities.
            using (var commandProcessor = new ViewerCommandProcessor(String.Format("Processing Sop Instance {0}", result.SopInstanceUid)))
            {
                try
                {
                    var    studyLocation   = new StudyLocation(result.StudyInstanceUid);
                    String destinationFile = studyLocation.GetSopInstancePath(result.SeriesInstanceUid, result.SopInstanceUid);

                    DicomFile file = ConvertToDicomFile(message, destinationFile, _context.SourceAE);

                    // Create the Study Folder, if need be
                    commandProcessor.AddCommand(new CreateDirectoryCommand(studyLocation.StudyFolder));

                    bool   duplicateFile = false;
                    string dupName       = null;

                    if (File.Exists(destinationFile))
                    {
                        // TODO (CR Jun 2012): Shouldn't the commands themselves make this decision at the time
                        // the file is being saved? Otherwise, what happens if the same SOP were being saved 2x simultaneously.
                        // I know the odds are low, but just pointing it out.
                        duplicateFile   = true;
                        dupName         = Guid.NewGuid().ToString() + ".dcm";
                        destinationFile = Path.Combine(Path.GetDirectoryName(destinationFile), dupName);
                    }

                    if (fileImportBehaviour == FileImportBehaviourEnum.Move)
                    {
                        commandProcessor.AddCommand(new RenameFileCommand(file.Filename, destinationFile, true));
                    }
                    else if (fileImportBehaviour == FileImportBehaviourEnum.Copy)
                    {
                        commandProcessor.AddCommand(new CopyFileCommand(file.Filename, destinationFile, true));
                    }
                    else if (fileImportBehaviour == FileImportBehaviourEnum.Save)
                    {
                        commandProcessor.AddCommand(new SaveDicomFileCommand(destinationFile, file, true));
                    }

                    var insertWorkItemCommand = CreateWorkItemCommand(workItem, result, file, duplicateFile, dupName);
                    commandProcessor.AddCommand(insertWorkItemCommand);

                    if (commandProcessor.Execute())
                    {
                        result.DicomStatus = DicomStatuses.Success;
                        IncrementTotalFiles(insertWorkItemCommand, result.StudyInstanceUid);
                    }
                    else
                    {
                        if (commandProcessor.FailureException is ChangeConflictException ||
                            commandProcessor.FailureException is SqlCeLockTimeoutException)
                        {
                            result.RetrySuggested = true;     // Change conflict or lock timeout may work if we just retry
                        }
                        Platform.Log(LogLevel.Warn, "Failure Importing file: {0}", file.Filename);
                        string failureMessage = String.Format(
                            "Failure processing message: {0}. Sending failure status.",
                            commandProcessor.FailureReason);
                        result.SetError(DicomStatuses.ProcessingFailure, failureMessage);

                        // processor already rolled back
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Error, e, "Unexpected exception when {0}.  Rolling back operation.", commandProcessor.Description);
                    commandProcessor.Rollback();
                    result.SetError(result.DicomStatus ?? DicomStatuses.ProcessingFailure, e.Message);
                }
            }
        }
        /// <summary>
        /// Imports the specified <see cref="DicomMessageBase"/> object into the system.
        /// The object will be inserted into the <see cref="WorkItem"/> for processing
        /// </summary>
        /// <param name="message">The DICOM object to be imported.</param>
        /// <param name="badFileBehavior"> </param>
        /// <param name="fileImportBehaviour"> </param>
        /// <returns>An instance of <see cref="DicomProcessingResult"/> that describes the result of the processing.</returns>
        /// <exception cref="DicomDataException">Thrown when the DICOM object contains invalid data</exception>
        public DicomProcessingResult Import(DicomMessageBase message, BadFileBehaviourEnum badFileBehavior, FileImportBehaviourEnum fileImportBehaviour)
        {
            Platform.CheckForNullReference(message, "message");
            String studyInstanceUid  = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
            String seriesInstanceUid = message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
            String sopInstanceUid    = message.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);
            String accessionNumber   = message.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty);
            String patientsName      = message.DataSet[DicomTags.PatientsName].GetString(0, string.Empty);
            String patientId         = message.DataSet[DicomTags.PatientId].GetString(0, string.Empty);

            var result = new DicomProcessingResult
            {
                Successful        = true,
                StudyInstanceUid  = studyInstanceUid,
                SeriesInstanceUid = seriesInstanceUid,
                SopInstanceUid    = sopInstanceUid,
                AccessionNumber   = accessionNumber,
                PatientsName      = patientsName,
                PatientId         = patientId,
            };

            WorkItem workItem;

            lock (_context.StudyWorkItemsSyncLock)
                _context.StudyWorkItems.TryGetValue(studyInstanceUid, out workItem);

            try
            {
                Validate(message);
            }
            catch (DicomDataException e)
            {
                result.SetError(DicomStatuses.ProcessingFailure, e.Message);
                AuditFailure(result);
                return(result);
            }

            if (workItem != null)
            {
                if (workItem.Status == WorkItemStatusEnum.Deleted || workItem.Status == WorkItemStatusEnum.DeleteInProgress || workItem.Status == WorkItemStatusEnum.Canceled || workItem.Status == WorkItemStatusEnum.Canceling)
                {
                    // TODO Marmot (CR June 2012): not DicomStatuses.Cancel?
                    result.SetError(DicomStatuses.StorageStorageOutOfResources, "Canceled by user");
                    AuditFailure(result);
                    return(result);
                }
            }

            if (LocalStorageMonitor.IsMaxUsedSpaceExceeded)
            {
                //The input to this method is a VALID DICOM file, and we know we should have stored it if it weren't for
                //the fact that we're out of disk space. So, we insert the work item UID anyway, knowing that it'll cause
                //the work item to fail. In fact, that's why we're doing it.
                result.SetError(DicomStatuses.StorageStorageOutOfResources, string.Format("Import failed, disk space usage exceeded"));
                InsertFailedWorkItemUid(workItem, message, result);

                _context.FatalError = true;
                AuditFailure(result);
                return(result);
            }

            Process(message, fileImportBehaviour, workItem, result);

            if (result.DicomStatus != DicomStatuses.Success)
            {
                if (result.RetrySuggested)
                {
                    Platform.Log(LogLevel.Warn,
                                 "Failure importing file with retry suggested, retrying Import of file: {0}",
                                 sopInstanceUid);

                    Process(message, fileImportBehaviour, workItem, result);
                }
            }

            if (result.DicomStatus != DicomStatuses.Success)
            {
                //The input to this method is a VALID DICOM file, and we know we should have stored it if it weren't for
                //the fact that we're out of disk space. So, we insert the work item UID anyway, knowing that it'll cause
                //the work item to fail. In fact, that's why we're doing it.
                InsertFailedWorkItemUid(workItem, message, result);

                AuditFailure(result);
            }

            return(result);
        }