private void LoadNewSeries(List <string> changedStudyInstanceUids)
        {
            const string segmentationModality = "SEG";

            foreach (string studyInstanceUid in changedStudyInstanceUids)
            {
                Study loadedStudy = ImageViewer.StudyTree.GetStudy(studyInstanceUid);
                if (loadedStudy == null)
                {
                    continue; // the given study is not loaded in this ImageViewer
                }
                // Query for new segmentation SOP Instances for the given study
                var seriesIdentifier = new SeriesIdentifier
                {
                    StudyInstanceUid = studyInstanceUid,
                    Modality         = segmentationModality
                };
                var seriesEntryRequest = new GetSeriesEntriesRequest
                {
                    Criteria = new SeriesEntry {
                        Series = seriesIdentifier
                    }
                };

                List <SeriesEntry> entries = null;
                Platform.GetService <IStudyStoreQuery>(
                    s =>
                    entries =
                        s.GetSeriesEntries(seriesEntryRequest)
                        .SeriesEntries.Where(
                            entry =>
                            loadedStudy.Series.All(series => series.SeriesInstanceUid != entry.Series.SeriesInstanceUid))
                        .ToList());

                // Get all unique AE Titles for the study. Can study have more than one?
                // We only need to query each AETitle once, or there will be duplicates/errors.
                List <IDicomServiceNode> studyAes =
                    (from seriesEntry in entries where seriesEntry != null select seriesEntry.Series.RetrieveAE).GroupBy
                    (
                        ae => ae.AETitle).Select(ae1 => ae1.First()).OfType <IDicomServiceNode>().ToList();

                if (!studyAes.Any())
                {
                    continue;
                }

                var reallyUpdatedStudies = new HashSet <string>();
                foreach (IDicomServiceNode studyAe in studyAes)
                {
                    IStudyLoader studyLoader;
                    try
                    {
                        studyLoader = studyAe.GetService <IStudyLoader>();
                    }
                    catch (Exception ex)
                    {
                        //Platform.Log(LogLevel.Error, ex, "Cannot get study loader", studyAe);
                        throw new Exception("Cannot get study loader", ex);
                    }

                    int numberOfSops =
                        studyLoader.Start(new StudyLoaderArgs(studyInstanceUid, null, new StudyLoaderOptions(true)));

                    // Load new segmentation SOP Instances
                    if (numberOfSops > 0)
                    {
                        for (int i = 0; i < numberOfSops; i++)
                        {
                            Sop sop = studyLoader.LoadNextSop();
                            if (sop != null && sop.Modality == segmentationModality)
                            {
                                try
                                {
                                    if (ImageViewer.StudyTree.AddSop(sop))
                                    {
                                        SegmentationDocument segmentationDocument =
                                            new SegmentationDeserializer(sop).DeserializeSegmenationDocument();
                                        if (segmentationDocument != null)
                                        {
                                            foreach (Seg seg in segmentationDocument.Segs)
                                            {
                                                IPresentationImage segPresentationImage = null;
                                                if (seg.ImageSeriesUid == null)
                                                {
                                                    if (seg.SegmentImageData != null &&
                                                        seg.SegmentImageData.SegmentFrameData != null &&
                                                        seg.SegmentImageData.SegmentFrameData.Count > 0)
                                                    {
                                                        foreach (
                                                            IImageBox imageBox in
                                                            ImageViewer.PhysicalWorkspace.ImageBoxes.Where(
                                                                imageBox => imageBox != null))
                                                        {
                                                            if (imageBox.DisplaySet != null)
                                                            {
                                                                segPresentationImage = SegmentationGraphicsHelpers.
                                                                                       PresentationImageFromPositionOrientation(
                                                                    seg.SegmentImageData.SegmentFrameData[0].
                                                                    ImagePositionPatient,
                                                                    seg.SegmentImageData.SegmentFrameData[0].
                                                                    ImageOrientationPatient,
                                                                    imageBox.DisplaySet,
                                                                    seg.SegmentImageData.FrameOfReferenceUid);
                                                            }
                                                            if (segPresentationImage != null)
                                                            {
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    segPresentationImage =
                                                        GetFirstPresentationImageForSeries(sop.StudyInstanceUid,
                                                                                           seg.ImageSeriesUid);
                                                }
                                                if (segPresentationImage == null)
                                                {
                                                    Platform.Log(LogLevel.Info,
                                                                 "Failed to find a series and image to display a segmentation frame on (SOP Instance UID={0}, Label = {1}) (New)",
                                                                 segmentationDocument.SopInstanceUid, seg.Label);
                                                }
                                                else
                                                {
                                                    SegmentationGraphicsHelpers.CreateSeriesGraphicsForSeg(
                                                        segPresentationImage, seg, segmentationDocument,
                                                        sop.DataSource as IDicomMessageSopDataSource);
                                                    reallyUpdatedStudies.Add(studyInstanceUid);
                                                }

                                                var sopProvider = segPresentationImage as ISopProvider;
                                                if (sopProvider != null)
                                                {
                                                    AddSegmentationMenuInfo(segmentationDocument, seg, sopProvider.Sop);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        sop.Dispose();
                                    }
                                }
                                catch (SopValidationException ex)
                                {
                                    Platform.Log(LogLevel.Error, ex,
                                                 "Failed to add newly loaded Segmentation SOP  to the StudyTree (studyInstanceUid={0}; SOPInstaceUID={1})",
                                                 sop.StudyInstanceUid, sop.SopInstanceUid);
                                    sop.Dispose();
                                }
                            }
                            else
                            {
                                sop.Dispose();
                            }
                        }
                    }
                }

                // Update component, if present
                if (reallyUpdatedStudies.Count > 0)
                {
                    UpdateSegmentationTreeInComponent();
                }
            }
        }
        /// <summary>
        /// Checks whether the specified series is loaded into the current ImageViewer.
        /// If not loaded, the method will load the series into the currently selected ImageBox.
        /// </summary>
        /// <param name="seriesInstanceUid">Series Instance UID to validate</param>
        /// <param name="imagePositionPatient">Image Position Patient from an image in the series</param>
        /// <param name="imageOrientationPatient">Image Orientation Patient from an image in the series</param>
        /// <param name="frameOfReferenceUid">Frame of Reference UID of the given series</param>
        /// <returns><value>true</value> is series now loaded, or <value>false</value> if no matching
        /// series could be found or loaded</returns>
        /// <remarks>Either <paramref name="seriesInstanceUid"/> or <paramref name="imagePositionPatient"/> and
        ///  <paramref name="imageOrientationPatient"/> must be not null</remarks>
        private bool EnsureSeriesIsLoaded(string seriesInstanceUid, double[] imagePositionPatient,
                                          double[] imageOrientationPatient, string frameOfReferenceUid)
        {
            if (string.IsNullOrEmpty(seriesInstanceUid) &&
                (imagePositionPatient == null || imageOrientationPatient == null))
            {
                return(false);
            }

            bool isLoaded = false;

            foreach (IImageBox imageBox in ImageViewer.PhysicalWorkspace.ImageBoxes.Where(
                         imageBox =>
                         imageBox != null && imageBox.DisplaySet != null && imageBox.DisplaySet.PresentationImages != null))
            {
                if (string.IsNullOrEmpty(seriesInstanceUid))
                {
                    IPresentationImage segPresentationImage = SegmentationGraphicsHelpers.
                                                              PresentationImageFromPositionOrientation(
                        imagePositionPatient,
                        imageOrientationPatient,
                        imageBox.DisplaySet,
                        frameOfReferenceUid);
                    if (segPresentationImage != null)
                    {
                        isLoaded = true;
                        break;
                    }
                }
                else
                {
                    IImageSopProvider imageSopProvider =
                        imageBox.DisplaySet.PresentationImages.OfType <IImageSopProvider>().FirstOrDefault();
                    if (imageSopProvider != null && imageSopProvider.Frame.SeriesInstanceUid == seriesInstanceUid)
                    {
                        isLoaded = true;
                        break;
                    }
                }
            }
            if (!isLoaded)
            {
                IImageBox targetImageBox = ImageViewer.PhysicalWorkspace.SelectedImageBox ??
                                           (ImageViewer.PhysicalWorkspace.ImageBoxes.Count > 0
                                                ? ImageViewer.PhysicalWorkspace.ImageBoxes[0]
                                                : null);
                if (targetImageBox == null)
                {
                    Platform.Log(LogLevel.Error, "Failed to find an ImageBox in which to load segmentation's series.");
                }
                else
                {
                    foreach (IImageSet imageSet in ImageViewer.LogicalWorkspace.ImageSets.Where(
                                 imageSet => imageSet != null && imageSet.DisplaySets != null))
                    {
                        foreach (IDisplaySet displaySet in imageSet.DisplaySets.Where(
                                     displaySet => displaySet != null && displaySet.PresentationImages != null))
                        {
                            if (string.IsNullOrEmpty(seriesInstanceUid))
                            {
                                IPresentationImage segPresentationImage = SegmentationGraphicsHelpers.
                                                                          PresentationImageFromPositionOrientation(
                                    imagePositionPatient,
                                    imageOrientationPatient,
                                    displaySet,
                                    frameOfReferenceUid);
                                if (segPresentationImage != null)
                                {
                                    IDisplaySet targetDisplaySet = displaySet.CreateFreshCopy();
                                    targetImageBox.DisplaySet = targetDisplaySet;
                                    // TODO - verify whether any of the Selected properties need re-setting
                                    isLoaded = true;
                                    break;
                                }
                            }
                            else
                            {
                                IImageSopProvider imageSopProvider =
                                    displaySet.PresentationImages.OfType <IImageSopProvider>().FirstOrDefault();
                                if (imageSopProvider != null &&
                                    imageSopProvider.Frame.SeriesInstanceUid == seriesInstanceUid)
                                {
                                    IDisplaySet targetDisplaySet = displaySet.CreateFreshCopy();
                                    targetImageBox.DisplaySet = targetDisplaySet;
                                    // TODO - verify whether any of the Selected properties need re-setting
                                    isLoaded = true;
                                    break;
                                }
                            }
                        }
                        if (isLoaded)
                        {
                            break;
                        }
                    }
                }
            }

            return(isLoaded);
        }
        private void OnDisplaySetChanged(object sender, DisplaySetChangedEventArgs e)
        {
            if (e.NewDisplaySet != null && e.NewDisplaySet.Visible)
            {
                var studyToSeriesAndInstanceDictionary = new Dictionary <string, Dictionary <string, IImageSopProvider> >();
                foreach (
                    IImageSopProvider imageSopPrivider in
                    e.NewDisplaySet.PresentationImages.OfType <IImageSopProvider>().Where(
                        imageSopPrivider => imageSopPrivider != null))
                {
                    if (imageSopPrivider != null)
                    {
                        string studyInstanceUid  = imageSopPrivider.ImageSop.StudyInstanceUid;
                        string seriesInstanceUid = imageSopPrivider.ImageSop.SeriesInstanceUid;

                        Dictionary <string, IImageSopProvider> seriesToSopInstanceDict;
                        if (studyToSeriesAndInstanceDictionary.ContainsKey(studyInstanceUid))
                        {
                            seriesToSopInstanceDict = studyToSeriesAndInstanceDictionary[studyInstanceUid];
                        }
                        else
                        {
                            seriesToSopInstanceDict = new Dictionary <string, IImageSopProvider>();
                            studyToSeriesAndInstanceDictionary[studyInstanceUid] = seriesToSopInstanceDict;
                        }

                        // Store one SOP Instance for each series
                        if (!seriesToSopInstanceDict.ContainsKey(seriesInstanceUid))
                        {
                            seriesToSopInstanceDict[seriesInstanceUid] = imageSopPrivider;
                        }
                    }
                }

                bool updateComponent = false;
                foreach (string studyInstanceUid in studyToSeriesAndInstanceDictionary.Keys)
                {
                    List <Sop> segmentationSopInstances = LoadSegmentationSopsForStudy(studyInstanceUid);
                    if (segmentationSopInstances != null)
                    {
                        foreach (Sop segSop in segmentationSopInstances)
                        {
                            SegmentationDocument segmentationDocument =
                                new SegmentationDeserializer(segSop).DeserializeSegmenationDocument();
                            if (segmentationDocument != null &&
                                !SegmentationGraphicsHelpers.IsSegmentationDocumentGraphicLoaded(segmentationDocument,
                                                                                                 e.NewDisplaySet))
                            {
                                foreach (Seg seg in segmentationDocument.Segs)
                                {
                                    IPresentationImage segPresentationImage = null;
                                    if (seg.ImageSeriesUid == null)
                                    {
                                        if (seg.SegmentImageData != null &&
                                            seg.SegmentImageData.SegmentFrameData != null &&
                                            seg.SegmentImageData.SegmentFrameData.Count > 0)
                                        {
                                            segPresentationImage = SegmentationGraphicsHelpers.
                                                                   PresentationImageFromPositionOrientation(
                                                seg.SegmentImageData.SegmentFrameData[0].ImagePositionPatient,
                                                seg.SegmentImageData.SegmentFrameData[0].ImageOrientationPatient,
                                                e.NewDisplaySet,
                                                seg.SegmentImageData.FrameOfReferenceUid);

                                            //var sop = segPresentationImage as IImageSopProvider;
                                            //if (sop != null)
                                            //{
                                            //    seg.ImageSeriesUid = sop.Frame.SeriesInstanceUid;
                                            //}
                                        }
                                    }
                                    else if (
                                        studyToSeriesAndInstanceDictionary[studyInstanceUid].ContainsKey(
                                            seg.ImageSeriesUid))
                                    {
                                        segPresentationImage =
                                            studyToSeriesAndInstanceDictionary[studyInstanceUid][seg.ImageSeriesUid] as
                                            IPresentationImage;
                                    }
                                    if (segPresentationImage == null)
                                    {
                                        Platform.Log(LogLevel.Info,
                                                     "Failed to find a series and image to display a segmentation frame on (SOP Instance UID={0}, Label = {1})",
                                                     segmentationDocument.SopInstanceUid, seg.Label);
                                    }
                                    else
                                    {
                                        SegmentationGraphicsHelpers.CreateSeriesGraphicsForSeg(
                                            segPresentationImage, seg, segmentationDocument,
                                            segSop.DataSource as IDicomMessageSopDataSource);
                                        updateComponent = true;
                                    }

                                    var sopProvider = segPresentationImage as ISopProvider;
                                    if (sopProvider != null)
                                    {
                                        AddSegmentationMenuInfo(segmentationDocument, seg, sopProvider.Sop);
                                    }
                                }
                            }
                        }
                    }
                }

                // Update component if new graphics is loaded
                if (updateComponent)
                {
                    UpdateSegmentationTreeInComponent();
                }
            }
        }