static FExtent GetFExtent(int srcLength, int weightsLength)
        {
            FExtentKey key = new FExtentKey(srcLength, weightsLength);

            FExtent extent;

            lock (fCache)
            {
                extent = (FExtent)fCache[key];
            }

            int fOffset = -weightsLength / 2;

            if (extent == null)
            {
                extent         = new FExtent();
                extent.fStarts = new int[srcLength];
                extent.fEnds   = new int[srcLength];

                for (int dst = 0; dst < srcLength; ++dst)
                {
                    int startSrc = dst + fOffset;

                    if (startSrc < 0)
                    {
                        extent.fStarts[dst] = -startSrc;
                    }
                    else
                    {
                        extent.fStarts[dst] = 0;
                    }

                    int end      = startSrc + weightsLength;
                    int endDelta = srcLength - end;

                    if (endDelta < 0)
                    {
                        extent.fEnds[dst] = weightsLength + endDelta;
                    }
                    else
                    {
                        extent.fEnds[dst] = weightsLength;
                    }
                }

                lock (fCache)
                {
                    if (fCache.Count > 16)
                    {
                        object top = fCacheQ.Dequeue();
                        fCache.Remove(top);
                    }

                    fCache[key] = extent;
                    fCacheQ.Enqueue(key);
                }
            }

            return(extent);
        }
        private static FExtent GetFExtent(int srcLength, int weightsLength)
        {
            FExtentKey key = new FExtentKey(srcLength, weightsLength);

            FExtent extent;
            lock (fCache)
            {
                extent = (FExtent)fCache[key];
            }

            int fOffset = -weightsLength / 2;

            if (extent == null)
            {
                extent = new FExtent();
                extent.fStarts = new int[srcLength];
                extent.fEnds = new int[srcLength];

                for (int dst = 0; dst < srcLength; ++dst)
                {
                    int startSrc = dst + fOffset;

                    if (startSrc < 0)
                    {
                        extent.fStarts[dst] = -startSrc;
                    }
                    else
                    {
                        extent.fStarts[dst] = 0;
                    }

                    int end = startSrc + weightsLength;
                    int endDelta = srcLength - end;
                
                    if (endDelta < 0)
                    {
                        extent.fEnds[dst] = weightsLength + endDelta;
                    }
                    else
                    {
                        extent.fEnds[dst] = weightsLength;
                    }
                }
                
                lock (fCache)
                {
                    if (fCache.Count > 16)
                    {
                        object top = fCacheQ.Dequeue();
                        fCache.Remove(top);
                    }

                    fCache[key] = extent;
                    fCacheQ.Enqueue(key);
                }
            }

            return extent;
        }
            public override bool Equals(object obj)
            {
                FExtentKey fek = (FExtentKey)obj;

                return(srcLength == fek.srcLength && weightsLength == fek.weightsLength);
            }