private UnaryPipe <TKey, TPayload, TPayload> GetPipe(IStreamObserver <TKey, TPayload> observer)
        {
            var lookupKey = CacheKey.Create();

            var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => QuantizeLifetimeTemplate.Generate(this));
            Func <PlanNode, IQueryObject, PlanNode> planNode = ((PlanNode p, IQueryObject o) => new PointAtEndPlanNode(p, o, typeof(TKey), typeof(TPayload), true, generatedPipeType.Item2, false));

            var instance    = Activator.CreateInstance(generatedPipeType.Item1, this, observer, this.width, this.skip, this.offset, planNode);
            var returnValue = (UnaryPipe <TKey, TPayload, TPayload>)instance;

            return(returnValue);
        }
        internal static Tuple <Type, string> Generate <TKey, TPayload>(QuantizeLifetimeStreamable <TKey, TPayload> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TPayload>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

#if CODEGEN_TIMING
            Stopwatch sw = new Stopwatch();
            sw.Start();
#endif
            var template = new QuantizeLifetimeTemplate(
                $"GeneratedQuantizeLifetime_{QuantizeLifetimeSequenceNumber++}",
                typeof(TKey), typeof(TPayload));

            return(template.Generate <TKey, TPayload>(typeof(IStreamable <,>)));
        }