public HeaderLoader(HeaderStreamingContext context)
        {
            _studyInstanceUid = context.Parameters.StudyInstanceUID;
            _partitionAE      = context.Parameters.ServerAETitle;
            _statistics.FindStudyFolder.Start();
            string sessionId = context.CallerAE;

            ServerPartition partition = ServerPartitionMonitor.Instance.GetPartition(_partitionAE);

            StudyStorageLoader storageLoader = new StudyStorageLoader(sessionId);

            storageLoader.CacheEnabled       = ImageStreamingServerSettings.Default.EnableCache;
            storageLoader.CacheRetentionTime = ImageStreamingServerSettings.Default.CacheRetentionWindow;
            StudyLocation = storageLoader.Find(_studyInstanceUid, partition);

            if (StudyLocation != null && StudyLocation.QueueStudyStateEnum != QueueStudyStateEnum.Idle)
            {
                Platform.Log(LogLevel.Warn, "Accessing to study {0} while its current state is {1}",
                             StudyLocation.StudyInstanceUid, StudyLocation.QueueStudyStateEnum);
            }

            _statistics.FindStudyFolder.End();
        }
        public Stream GetStudyHeader(string callingAETitle, HeaderStreamingParameters parameters)
        {
            ConnectionMonitor.GetMonitor(OperationContext.Current.Host).AddContext(OperationContext.Current);

            HeaderStreamingStatistics stats = new HeaderStreamingStatistics();

            stats.ProcessTime.Start();

            HeaderLoader loader = null;

            try
            {
                Platform.CheckForEmptyString(callingAETitle, "callingAETitle");
                Platform.CheckForNullReference(parameters, "parameters");
                Platform.CheckForEmptyString(parameters.ReferenceID, "parameters.ReferenceID");
                Platform.CheckForEmptyString(parameters.ServerAETitle, "parameters.ServerAETitle");
                Platform.CheckForEmptyString(parameters.StudyInstanceUID, "parameters.StudyInstanceUID");

                Platform.Log(LogLevel.Debug, "Received request from {0}. Ref # {1} ", callingAETitle, parameters.ReferenceID);

                HeaderStreamingContext context = new HeaderStreamingContext();
                context.ServiceInstanceID = ID;
                context.CallerAE          = callingAETitle;
                context.Parameters        = parameters;

                // TODO: perform permission check on callingAETitle

                loader = new HeaderLoader(context);

                if (!parameters.IgnoreInUse)
                {
                    if (!loader.StudyLocation.CanBeUsedForDiagnostics())
                    {
                        throw new StudyAccessException(SR.FaultFaultStudyTemporarilyNotAccessible, loader.StudyLocation.QueueStudyStateEnum, null);
                    }
                }

                Stream stream = loader.Load();
                if (stream == null)
                {
                    throw new FaultException(loader.FaultDescription);
                }

                Platform.Log(LogLevel.Debug, "Response sent to {0}. Ref # {1} ", callingAETitle, parameters.ReferenceID);

                return(stream);
            }
            catch (ArgumentException e)
            {
                throw new FaultException(e.Message);
            }
            catch (StudyNotFoundException)
            {
                throw new FaultException <StudyNotFoundFault>(
                          new StudyNotFoundFault(), String.Format(SR.FaultNotExists, parameters.StudyInstanceUID, parameters.ServerAETitle));
            }
            catch (StudyIsNearlineException e)
            {
                throw new FaultException <StudyIsNearlineFault>(
                          new StudyIsNearlineFault()
                {
                    IsStudyBeingRestored = e.RestoreRequested
                },
                          String.Format(SR.FaultStudyIsNearline, parameters.StudyInstanceUID));
            }
            catch (StudyAccessException e)
            {
                if (e.InnerException != null)
                {
                    if (e.InnerException is FileNotFoundException)
                    {
                        throw new FaultException <StudyIsInUseFault>(
                                  new StudyIsInUseFault(e.StudyState.Description),
                                  String.Format(SR.FaultFaultStudyTemporarilyNotAccessible, parameters.StudyInstanceUID, e.StudyState));
                    }
                }
                throw new FaultException <StudyIsInUseFault>(
                          new StudyIsInUseFault(e.StudyState.Description),
                          String.Format(SR.FaultFaultStudyTemporarilyNotAccessible, parameters.StudyInstanceUID, e.StudyState));
            }
            catch (FilesystemNotReadableException e)
            {
                //interpret as generic fault
                throw new FaultException(e.Message);
            }
            catch (FileNotFoundException e)
            {
                // OOPS.. the header is missing
                Platform.Log(LogLevel.Error, e, "Unable to process study header request from {0}", callingAETitle);
                throw new FaultException(SR.FaultHeaderIsNotAvailable);
            }
            catch (Exception e)
            {
                if (!(e is FaultException))
                {
                    Platform.Log(LogLevel.Error, e, "Unable to process study header request from {0}", callingAETitle);
                }

                throw new FaultException(e.Message);
            }
            finally
            {
                stats.ProcessTime.End();

                if (loader != null && Settings.Default.LogStatistics)
                {
                    stats.AddField("StudyInstanceUid", parameters.StudyInstanceUID);

                    stats.AddSubStats(loader.Statistics);
                    StatisticsLogger.Log(LogLevel.Info, stats);
                }
            }
        }