/// <summary>
        /// Gets the VOI data LUTs for specified frame.
        /// </summary>
        /// <param name="frameNumber"></param>
        /// <returns></returns>
        internal IList <VoiDataLut> GetFrameVoiDataLuts(int frameNumber)
        {
            Platform.CheckPositive(frameNumber, "frameNumber");

            lock (_syncLock)
            {
                var cacheKey = VoiDataLutsCacheKey.RootKey;
                var dataset  = (IDicomAttributeProvider)DataSource;

                // attempt to find the VOI LUT Sequence in a functional group pertaining to the requested frame
                bool           isFrameSpecific;
                DicomAttribute dicomAttribute;
                var            item = _functionalGroups.GetFrameFunctionalGroupItem(frameNumber, DicomTags.VoiLutSequence, out isFrameSpecific);
                if (item != null && item.TryGetAttribute(DicomTags.VoiLutSequence, out dicomAttribute))
                {
                    cacheKey = isFrameSpecific ? VoiDataLutsCacheKey.GetFrameKey(frameNumber) : VoiDataLutsCacheKey.SharedKey;
                    dataset  = item;
                }

                IList <VoiDataLut> dataLuts;
                if (!_frameVoiDataLuts.TryGetValue(cacheKey, out dataLuts))
                {
                    _frameVoiDataLuts.Add(cacheKey, dataLuts = CreateVoiDataLuts(dataset));
                }
                return(dataLuts);
            }
        }