/// <summary>
        /// Use instead of IGrain.AsReference() and IGrain.Cast()!
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="this"></param>
        /// <returns></returns>
        public static T CastAs <T>(this IGrain @this) where T : IGrain
        {
            //in place to short-circuit Orleans when testing; should always be used

            var proxy = @this as GrainProxy;

            if (proxy != null)
            {
                return((T)(object)proxy); //eeek!
            }

            var grain = @this as Grain;

            if (grain != null)
            {
                //need to proxy here - but how can we know what key, and what interface(s), we are proxying?
                //the grain itself is kind of agnostic to this. Except that it isn't - it will need to carry
                //round its 'activation context' where it clings still to the data that begot it.

                //A placement, as well as carrying concrete type, therefore also needs to carry the initializing abstract key.
                //But what then to do with other keys that resolve to the same?

                //Or do we proxify with the full set of interfaces the grain supports? Can't do - as the resolution logic may be different for other interfaces -
                //roundtripping may not be possible, and therefore the intended reference will point elsewhere...


                throw new NotImplementedException("Need to give access to key via GrainRuntime extraction");

                //var harness = ExtractGrainRuntimeFrom(@this) as GrainHarness; //the GrainRuntime needs to give access to

                //if(harness != null) {
                //    var concreteKey = @this.GetGrainKey();

                //    var grainKey = new ResolvedKey(typeof(T), concreteKey.AbstractType, concreteKey.Id);

                //    return (T)(object)harness.Fixture.GetGrainProxy(grainKey);
                //}
            }

            return(@this.AsReference <T>());
        }
        private Func <object, Task> GetTimerFunc(IProviderRuntime providerRuntime, IGrain grain)
        {
            var grainName = grain.GetType().FullName;

            return(async o =>
            {
                var filterableGrain = grain.AsReference <IFilterableGrain>();
                var result = await filterableGrain.GetFilters();

                if (result != null)
                {
                    var filterGrain = providerRuntime.GrainFactory.GetGrain <ITypeFilterGrain>(grain.GetType().FullName);
                    await filterGrain.RegisterFilter(grainName, filterableGrain.GetPrimaryKey().ToString(), result);

                    var filterString = string.Join(",", result.Select(p => $"{p.FilterName} : {p.Value}"));
                    _logger.Verbose($"Filters for grain [Type : {grainName}] [Id : {grain.GetPrimaryKey()}][Filter : {filterString}]");
                }
                else
                {
                    _logger.Verbose("Filter was not set yet");
                }
            });
        }