text:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;

using Orleans.Core;
using Orleans.GrainDirectory;
using Orleans.Providers;
using Orleans.Runtime.Configuration;
using Orleans.Runtime.GrainDirectory;
using Orleans.Runtime.Placement;
using Orleans.Runtime.Scheduler;
using Orleans.Storage;

namespace Orleans.Runtime
{
    internal class Catalog : SystemTarget, ICatalog, IPlacementContext, ISiloStatusListener
    {
        /// <summary>
        /// Exception to indicate that the activation would have been a duplicate so messages pending for it should be redirected.
        /// </summary>
        [Serializable]
        internal class DuplicateActivationException : Exception
        {
            public ActivationAddress ActivationToUse { get; private set; }

            public SiloAddress PrimaryDirectoryForGrain { get; private set; } // for diagnostics only!

            public DuplicateActivationException() : base("DuplicateActivationException") { }
            public DuplicateActivationException(string msg) : base(msg) { }
            public DuplicateActivationException(string message, Exception innerException) : base(message, innerException) { }

            public DuplicateActivationException(ActivationAddress activationToUse)
                : base("DuplicateActivationException")
            {
                ActivationToUse = activationToUse;
            }

            public DuplicateActivationException(ActivationAddress activationToUse, SiloAddress primaryDirectoryForGrain)
                : base("DuplicateActivationException")
            {
                ActivationToUse = activationToUse;
                PrimaryDirectoryForGrain = primaryDirectoryForGrain;
            }

            // Implementation of exception serialization with custom properties according to:
            // http://stackoverflow.com/questions/94488/what-is-the-correct-way-to-make-a-custom-net-exception-serializable
            protected DuplicateActivationException(SerializationInfo info, StreamingContext context)
                : base(info, context)
            {
                if (info != null)
                {
                    ActivationToUse = (ActivationAddress) info.GetValue("ActivationToUse", typeof (ActivationAddress));
                    PrimaryDirectoryForGrain = (SiloAddress) info.GetValue("PrimaryDirectoryForGrain", typeof (SiloAddress));
                }
            }

            public override void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                if (info != null)
                {
                    info.AddValue("ActivationToUse", ActivationToUse, typeof (ActivationAddress));
                    info.AddValue("PrimaryDirectoryForGrain", PrimaryDirectoryForGrain, typeof (SiloAddress));
                }
                // MUST call through to the base class to let it save its own state
                base.GetObjectData(info, context);
            }
        }

        [Serializable]
        internal class NonExistentActivationException : Exception
        {
            public ActivationAddress NonExistentActivation { get; private set; }

            public bool IsStatelessWorker { get; private set; }

            public NonExistentActivationException() : base("NonExistentActivationException") { }
            public NonExistentActivationException(string msg) : base(msg) { }
            public NonExistentActivationException(string message, Exception innerException)
                : base(message, innerException) { }

            public NonExistentActivationException(string msg, ActivationAddress nonExistentActivation, bool isStatelessWorker)
                : base(msg)
            {
                NonExistentActivation = nonExistentActivation;
                IsStatelessWorker = isStatelessWorker;
            }

            protected NonExistentActivationException(SerializationInfo info, StreamingContext context)
                : base(info, context)
            {
                if (info != null)
                {
                    NonExistentActivation = (ActivationAddress)info.GetValue("NonExistentActivation", typeof(ActivationAddress));
                    IsStatelessWorker = (bool)info.GetValue("IsStatelessWorker", typeof(bool));
                }
            }

            public override void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                if (info != null)
                {
                    info.AddValue("NonExistentActivation", NonExistentActivation, typeof(ActivationAddress));
                    info.AddValue("IsStatelessWorker", IsStatelessWorker, typeof(bool));
                }
                // MUST call through to the base class to let it save its own state
                base.GetObjectData(info, context);
            }
        }

        public GrainTypeManager GrainTypeManager { get; private set; }
        public SiloAddress LocalSilo { get; private set; }
        internal ISiloStatusOracle SiloStatusOracle { get; set; }
        internal readonly ActivationCollector ActivationCollector;

        private readonly ILocalGrainDirectory directory;
        private readonly OrleansTaskScheduler scheduler;
        private readonly ActivationDirectory activations;
        private IStorageProviderManager storageProviderManager;
        private Dispatcher dispatcher;
        private readonly Logger logger;
        private int collectionNumber;
        private int destroyActivationsNumber;
        private IDisposable gcTimer;
        private readonly GlobalConfiguration config;
        private readonly string localSiloName;
        private readonly CounterStatistic activationsCreated;
        private readonly CounterStatistic activationsDestroyed;
        private readonly CounterStatistic activationsFailedToActivate;
        private readonly IntValueStatistic inProcessRequests;
        private readonly CounterStatistic collectionCounter;
        private readonly GrainCreator grainCreator;

        internal Catalog(
            GrainId grainId,
            SiloAddress silo,
            string siloName,
            ILocalGrainDirectory grainDirectory,
            GrainTypeManager typeManager,
            OrleansTaskScheduler scheduler,
            ActivationDirectory activationDirectory,
            ClusterConfiguration config,
            GrainCreator grainCreator,
            out Action<Dispatcher> setDispatcher)
            : base(grainId, silo)
        {
            LocalSilo = silo;
            localSiloName = siloName;
            directory = grainDirectory;
            activations = activationDirectory;
            this.scheduler = scheduler;
            GrainTypeManager = typeManager;
            collectionNumber = 0;
            destroyActivationsNumber = 0;
            this.grainCreator = grainCreator;

            logger = LogManager.GetLogger("Catalog", Runtime.LoggerType.Runtime);
            this.config = config.Globals;
            setDispatcher = d => dispatcher = d;
            ActivationCollector = new ActivationCollector(config);
            GC.GetTotalMemory(true); // need to call once w/true to ensure false returns OK value

            config.OnConfigChange("Globals/Activation", () => scheduler.RunOrQueueAction(Start, SchedulingContext), false);
            IntValueStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_COUNT, () => activations.Count);
            activationsCreated = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_CREATED);
            activationsDestroyed = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_DESTROYED);
            activationsFailedToActivate = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_FAILED_TO_ACTIVATE);
            collectionCounter = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_COLLECTION_NUMBER_OF_COLLECTIONS);
            inProcessRequests = IntValueStatistic.FindOrCreate(StatisticNames.MESSAGING_PROCESSING_ACTIVATION_DATA_ALL, () =>
            {
                long counter = 0;
                lock (activations)
                {
                    foreach (var activation in activations)
                    {
                        ActivationData data = activation.Value;
                        counter += data.GetRequestCount();
                    }
                }
                return counter;
            });
        }

        internal void SetStorageManager(IStorageProviderManager storageManager)
        {
            storageProviderManager = storageManager;
        }

        internal void Start()
        {
            if (gcTimer != null) gcTimer.Dispose();

            var t = GrainTimer.FromTaskCallback(OnTimer, null, TimeSpan.Zero, ActivationCollector.Quantum, "Catalog.GCTimer");
            t.Start();
            gcTimer = t;
        }

        private Task OnTimer(object _)
        {
            return CollectActivationsImpl(true);
        }

        public Task CollectActivations(TimeSpan ageLimit)
        {
            return CollectActivationsImpl(false, ageLimit);
        }

        private async Task CollectActivationsImpl(bool scanStale, TimeSpan ageLimit = default(TimeSpan))
        {
            var watch = new Stopwatch();
            watch.Start();
            var number = Interlocked.Increment(ref collectionNumber);
            long memBefore = GC.GetTotalMemory(false) / (1024 * 1024);
            logger.Info(ErrorCode.Catalog_BeforeCollection, "Before collection#{0}: memory={1}MB, #activations={2}, collector={3}.",
                number, memBefore, activations.Count, ActivationCollector.ToString());
            List<ActivationData> list = scanStale ? ActivationCollector.ScanStale() : ActivationCollector.ScanAll(ageLimit);
            collectionCounter.Increment();
            var count = 0;
            if (list != null && list.Count > 0)
            {
                count = list.Count;
                if (logger.IsVerbose) logger.Verbose("CollectActivations{0}", list.ToStrings(d => d.Grain.ToString() + d.ActivationId));
                await DeactivateActivationsFromCollector(list);
            }
            long memAfter = GC.GetTotalMemory(false) / (1024 * 1024);
            watch.Stop();
            logger.Info(ErrorCode.Catalog_AfterCollection, "After collection#{0}: memory={1}MB, #activations={2}, collected {3} activations, collector={4}, collection time={5}.",
                number, memAfter, activations.Count, count, ActivationCollector.ToString(), watch.Elapsed);
        }

        public List<Tuple<GrainId, string, int>> GetGrainStatistics()
        {
            var counts = new Dictionary<string, Dictionary<GrainId, int>>();
            lock (activations)
            {
                foreach (var activation in activations)
                {
                    ActivationData data = activation.Value;
                    if (data == null || data.GrainInstance == null) continue;

                    // TODO: generic type expansion
                    var grainTypeName = TypeUtils.GetFullName(data.GrainInstanceType);

                    Dictionary<GrainId, int> grains;
                    int n;
                    if (!counts.TryGetValue(grainTypeName, out grains))
                    {
                        counts.Add(grainTypeName, new Dictionary<GrainId, int> { { data.Grain, 1 } });
                    }
                    else if (!grains.TryGetValue(data.Grain, out n))
                        grains[data.Grain] = 1;
                    else
                        grains[data.Grain] = n + 1;
                }
            }
            return counts
                .SelectMany(p => p.Value.Select(p2 => Tuple.Create(p2.Key, p.Key, p2.Value)))
                .ToList();
        }

        public List<DetailedGrainStatistic> GetDetailedGrainStatistics(string[] types=null)
        {
            var stats = new List<DetailedGrainStatistic>();
            lock (activations)
            {
                foreach (var activation in activations)
                {
                    ActivationData data = activation.Value;
                    if (data == null || data.GrainInstance == null) continue;

                    if (types==null || types.Contains(TypeUtils.GetFullName(data.GrainInstanceType)))
                    {
                        stats.Add(new DetailedGrainStatistic()
                        {
                            GrainType = TypeUtils.GetFullName(data.GrainInstanceType),
                            GrainIdentity = data.Grain,
                            SiloAddress = data.Silo,
                            Category = data.Grain.Category.ToString()
                        });
                    }
                }
            }
            return stats;
        }

        public IEnumerable<KeyValuePair<string, long>> GetSimpleGrainStatistics()
        {
            return activations.GetSimpleGrainStatistics();
        }

        public DetailedGrainReport GetDetailedGrainReport(GrainId grain)
        {
            var report = new DetailedGrainReport
            {
                Grain = grain,
                SiloAddress = LocalSilo,
                SiloName = localSiloName,
                LocalCacheActivationAddresses = directory.GetLocalCacheData(grain),
                LocalDirectoryActivationAddresses = directory.GetLocalDirectoryData(grain).Addresses,
                PrimaryForGrain = directory.GetPrimaryForGrain(grain)
            };
            try
            {
                PlacementStrategy unused;
                MultiClusterRegistrationStrategy unusedActivationStrategy;
                string grainClassName;
                GrainTypeManager.GetTypeInfo(grain.GetTypeCode(), out grainClassName, out unused, out unusedActivationStrategy);
                report.GrainClassTypeName = grainClassName;
            }
            catch (Exception exc)
            {
                report.GrainClassTypeName = exc.ToString();
            }

            List<ActivationData> acts = activations.FindTargets(grain);
            report.LocalActivations = acts != null ?
                acts.Select(activationData => activationData.ToDetailedString()).ToList() :
                new List<string>();
            return report;
        }

        #region MessageTargets

        /// <summary>
        /// Register a new object to which messages can be delivered with the local lookup table and scheduler.
        /// </summary>
        /// <param name="activation"></param>
        public void RegisterMessageTarget(ActivationData activation)
        {
            var context = new SchedulingContext(activation);
            scheduler.RegisterWorkContext(context);
            activations.RecordNewTarget(activation);
            activationsCreated.Increment();
        }

        /// <summary>
        /// Unregister message target and stop delivering messages to it
        /// </summary>
        /// <param name="activation"></param>
        public void UnregisterMessageTarget(ActivationData activation)
        {
            activations.RemoveTarget(activation);

            // this should be removed once we've refactored the deactivation code path. For now safe to keep.
            ActivationCollector.TryCancelCollection(activation);
            activationsDestroyed.Increment();

            scheduler.UnregisterWorkContext(new SchedulingContext(activation));

            if (activation.GrainInstance == null) return;

            var grainTypeName = TypeUtils.GetFullName(activation.GrainInstanceType);
            activations.DecrementGrainCounter(grainTypeName);
            activation.SetGrainInstance(null);
        }

        /// <summary>
        /// FOR TESTING PURPOSES ONLY!!
        /// </summary>
        /// <param name="grain"></param>
        internal int UnregisterGrainForTesting(GrainId grain)
        {
            var acts = activations.FindTargets(grain);
            if (acts == null) return 0;

            int numActsBefore = acts.Count;
            foreach (var act in acts)
                UnregisterMessageTarget(act);

            return numActsBefore;
        }

        #endregion

        #region Grains

        internal bool IsReentrantGrain(ActivationId running)
        {
            ActivationData target;
            GrainTypeData data;
            return TryGetActivationData(running, out target) &&
                target.GrainInstance != null &&
                GrainTypeManager.TryGetData(TypeUtils.GetFullName(target.GrainInstanceType), out data) &&
                data.IsReentrant;
        }

        public void GetGrainTypeInfo(int typeCode, out string grainClass, out PlacementStrategy placement, out MultiClusterRegistrationStrategy activationStrategy, string genericArguments = null)
        {
            GrainTypeManager.GetTypeInfo(typeCode, out grainClass, out placement, out activationStrategy, genericArguments);
        }

        #endregion

        #region Activations

        public int ActivationCount { get { return activations.Count; } }

        /// <summary>
        /// If activation already exists, use it
        /// Otherwise, create an activation of an existing grain by reading its state.
        /// Return immediately using a dummy that will queue messages.
        /// Concurrently start creating and initializing the real activation and replace it when it is ready.
        /// </summary>
        /// <param name="address">Grain's activation address</param>
        /// <param name="newPlacement">Creation of new activation was requested by the placement director.</param>
        /// <param name="grainType">The type of grain to be activated or created</param>
        /// <param name="genericArguments">Specific generic type of grain to be activated or created</param>
        /// <param name="requestContextData">Request context data.</param>
        /// <param name="activatedPromise"></param>
        /// <returns></returns>
        public ActivationData GetOrCreateActivation(
            ActivationAddress address,
            bool newPlacement,
            string grainType,
            string genericArguments,
            Dictionary<string, object> requestContextData,
            out Task activatedPromise)
        {
            ActivationData result;
            activatedPromise = TaskDone.Done;
            PlacementStrategy placement;

            lock (activations)
            {
                if (TryGetActivationData(address.Activation, out result))
                {
                    return result;
                }

                int typeCode = address.Grain.GetTypeCode();
                string actualGrainType = null;
                MultiClusterRegistrationStrategy activationStrategy;

                if (typeCode != 0)
                {
                    GetGrainTypeInfo(typeCode, out actualGrainType, out placement, out activationStrategy, genericArguments);
                }
                else
                {
                    // special case for Membership grain.
                    placement = SystemPlacement.Singleton;
                    activationStrategy = ClusterLocalRegistration.Singleton;
                }

                if (newPlacement && !SiloStatusOracle.CurrentStatus.IsTerminating())
                {
                    // create a dummy activation that will queue up messages until the real data arrives
                    if (string.IsNullOrEmpty(grainType))
                    {
                        grainType = actualGrainType;
                    }

                    // We want to do this (RegisterMessageTarget) under the same lock that we tested TryGetActivationData. They both access ActivationDirectory.
                    result = new ActivationData(
                        address,
                        genericArguments,
                        placement,
                        activationStrategy,
                        ActivationCollector,
                        config.Application.GetCollectionAgeLimit(grainType));
                    RegisterMessageTarget(result);
                }
            } // End lock

            // Did not find and did not start placing new
            if (result == null)
            {
                var msg = String.Format("Non-existent activation: {0}, grain type: {1}.",
                                           address.ToFullString(), grainType);
                if (logger.IsVerbose) logger.Verbose(ErrorCode.CatalogNonExistingActivation2, msg);
                CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_NON_EXISTENT_ACTIVATIONS).Increment();
                throw new NonExistentActivationException(msg, address, placement is StatelessWorkerPlacement);
            }

            SetupActivationInstance(result, grainType, genericArguments);
            activatedPromise = InitActivation(result, grainType, genericArguments, requestContextData);
            return result;
        }

        private void SetupActivationInstance(ActivationData result, string grainType, string genericArguments)
        {
            lock (result)
            {
                if (result.GrainInstance == null)
                {
                    CreateGrainInstance(grainType, result, genericArguments);
                }
            }
        }

        private async Task InitActivation(ActivationData activation, string grainType, string genericArguments, Dictionary<string, object> requestContextData)
        {
            // We've created a dummy activation, which we'll eventually return, but in the meantime we'll queue up (or perform promptly)
            // the operations required to turn the "dummy" activation into a real activation
            ActivationAddress address = activation.Address;

            int initStage = 0;
            // A chain of promises that will have to complete in order to complete the activation
            // Register with the grain directory, register with the store if necessary and call the Activate method on the new activation.
            try
            {
                initStage = 1;
                await RegisterActivationInGrainDirectoryAndValidate(activation);

                initStage = 2;
                await SetupActivationState(activation, String.IsNullOrEmpty(genericArguments) ? grainType : $"{grainType}[{genericArguments}]");

                initStage = 3;
                await InvokeActivate(activation, requestContextData);

                ActivationCollector.ScheduleCollection(activation);

                // Success!! Log the result, and start processing messages
                if (logger.IsVerbose) logger.Verbose("InitActivation is done: {0}", address);
            }
            catch (Exception ex)
            {
                lock (activation)
                {
                    activation.SetState(ActivationState.Invalid);
                    try
                    {
                        UnregisterMessageTarget(activation);
                    }
                    catch (Exception exc)
                    {
                        logger.Warn(ErrorCode.Catalog_UnregisterMessageTarget4, String.Format("UnregisterMessageTarget failed on {0}.", activation), exc);
                    }

                    switch (initStage)
                    {
                        case 1: // failed to RegisterActivationInGrainDirectory

                            ActivationAddress target = null;
                            Exception dupExc;
                            // Failure!! Could it be that this grain uses single activation placement, and there already was an activation?
                            if (Utils.TryFindException(ex, typeof (DuplicateActivationException), out dupExc))
                            {
                                target = ((DuplicateActivationException) dupExc).ActivationToUse;
                                CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_DUPLICATE_ACTIVATIONS)
                                    .Increment();
                            }
                            activation.ForwardingAddress = target;
                            if (target != null)
                            {
                                var primary = ((DuplicateActivationException)dupExc).PrimaryDirectoryForGrain;
                                // If this was a duplicate, it's not an error, just a race.
                                // Forward on all of the pending messages, and then forget about this activation.
                                string logMsg = String.Format("Tried to create a duplicate activation {0}, but we'll use {1} instead. " +
                                    "GrainInstanceType is {2}. " +
                                                            "{3}" +
                                                            "Full activation address is {4}. We have {5} messages to forward.",
                                    address,
                                    target,
                                    activation.GrainInstanceType,
                                                primary != null ? "Primary Directory partition for this grain is " + primary + ". " : String.Empty,
                                    address.ToFullString(),
                                    activation.WaitingCount);
                                if (activation.IsUsingGrainDirectory)
                                {
                                    logger.Info(ErrorCode.Catalog_DuplicateActivation, logMsg);
                                }
                                else
                                {
                                    if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_DuplicateActivation, logMsg);
                                }
                                RerouteAllQueuedMessages(activation, target, "Duplicate activation", ex);
                            }
                            else
                            {
                                logger.Warn(ErrorCode.Runtime_Error_100064,
                                    String.Format("Failed to RegisterActivationInGrainDirectory for {0}.",
                                        activation), ex);
                                // Need to undo the registration we just did earlier
                                if (activation.IsUsingGrainDirectory)
                                {
                                    scheduler.RunOrQueueTask(() => directory.UnregisterAsync(address),
                                        SchedulingContext).Ignore();
                                }
                                RerouteAllQueuedMessages(activation, null,
                                    "Failed RegisterActivationInGrainDirectory", ex);
                            }
                            break;

                        case 2: // failed to setup persistent state

                            logger.Warn(ErrorCode.Catalog_Failed_SetupActivationState,
                                String.Format("Failed to SetupActivationState for {0}.", activation), ex);
                            // Need to undo the registration we just did earlier
                            if (activation.IsUsingGrainDirectory)
                            {
                                scheduler.RunOrQueueTask(() => directory.UnregisterAsync(address),
                                    SchedulingContext).Ignore();
                            }

                            RerouteAllQueuedMessages(activation, null, "Failed SetupActivationState", ex);
                            break;

                        case 3: // failed to InvokeActivate

                            logger.Warn(ErrorCode.Catalog_Failed_InvokeActivate,
                                String.Format("Failed to InvokeActivate for {0}.", activation), ex);
                            // Need to undo the registration we just did earlier
                            if (activation.IsUsingGrainDirectory)
                            {
                                scheduler.RunOrQueueTask(() => directory.UnregisterAsync(address),
                                    SchedulingContext).Ignore();
                            }

                            RerouteAllQueuedMessages(activation, null, "Failed InvokeActivate", ex);
                            break;
                    }
                }
                throw;
            }
        }

        /// <summary>
        /// Perform just the prompt, local part of creating an activation object
        /// Caller is responsible for registering locally, registering with store and calling its activate routine
        /// </summary>
        /// <param name="grainTypeName"></param>
        /// <param name="data"></param>
        /// <param name="genericArguments"></param>
        /// <returns></returns>
        private void CreateGrainInstance(string grainTypeName, ActivationData data, string genericArguments)
        {
            string grainClassName;
            var interfaceToClassMap = GrainTypeManager.GetGrainInterfaceToClassMap();
            if (!interfaceToClassMap.TryGetValue(grainTypeName, out grainClassName))
            {
                // Lookup from grain type code
                var typeCode = data.Grain.GetTypeCode();
                if (typeCode != 0)
                {
                    PlacementStrategy unused;
                    MultiClusterRegistrationStrategy unusedActivationStrategy;
                    GetGrainTypeInfo(typeCode, out grainClassName, out unused, out unusedActivationStrategy, genericArguments);
                }
                else
                {
                    grainClassName = grainTypeName;
                }
            }

            GrainTypeData grainTypeData = GrainTypeManager[grainClassName];

            //Get the grain's type
            Type grainType = grainTypeData.Type;

            //Gets the type for the grain's state
            Type stateObjectType = grainTypeData.StateObjectType;

            lock (data)
            {
                Grain grain;

                //Create a new instance of a stateless grain
                if (stateObjectType == null)
                {
                    //Create a new instance of the given grain type
                    grain = grainCreator.CreateGrainInstance(grainType, data.Identity);
                }
                //Create a new instance of a stateful grain
                else
                {
                    SetupStorageProvider(grainType, data);
                    grain = grainCreator.CreateGrainInstance(grainType, data.Identity, stateObjectType, data.StorageProvider);
                }
                grain.Data = data;
                data.SetGrainInstance(grain);
            }

            activations.IncrementGrainCounter(grainClassName);

            if (logger.IsVerbose) logger.Verbose("CreateGrainInstance {0}{1}", data.Grain, data.ActivationId);
        }

        private void SetupStorageProvider(Type grainType, ActivationData data)
        {
            var grainTypeName = grainType.FullName;

            // Get the storage provider name, using the default if not specified.
            var attr = grainType.GetTypeInfo().GetCustomAttributes<StorageProviderAttribute>(true).FirstOrDefault();
            var storageProviderName = attr != null ? attr.ProviderName : Constants.DEFAULT_STORAGE_PROVIDER_NAME;

            IStorageProvider provider;
            if (storageProviderManager == null || storageProviderManager.GetNumLoadedProviders() == 0)
            {
                var errMsg = string.Format("No storage providers found loading grain type {0}", grainTypeName);
                logger.Error(ErrorCode.Provider_CatalogNoStorageProvider_1, errMsg);
                throw new BadProviderConfigException(errMsg);
            }
            if (string.IsNullOrWhiteSpace(storageProviderName))
            {
                // Use default storage provider
                provider = storageProviderManager.GetDefaultProvider();
            }
            else
            {
                // Look for MemoryStore provider as special case name
                bool caseInsensitive = Constants.MEMORY_STORAGE_PROVIDER_NAME.Equals(storageProviderName, StringComparison.OrdinalIgnoreCase);
                storageProviderManager.TryGetProvider(storageProviderName, out provider, caseInsensitive);
                if (provider == null)
                {
                    var errMsg = string.Format(
                        "Cannot find storage provider with Name={0} for grain type {1}", storageProviderName,
                        grainTypeName);
                    logger.Error(ErrorCode.Provider_CatalogNoStorageProvider_2, errMsg);
                    throw new BadProviderConfigException(errMsg);
                }
            }
            data.StorageProvider = provider;

            if (logger.IsVerbose2)
            {
                string msg = string.Format("Assigned storage provider with Name={0} to grain type {1}",
                    storageProviderName, grainTypeName);
                logger.Verbose2(ErrorCode.Provider_CatalogStorageProviderAllocated, msg);
            }
        }

        private async Task SetupActivationState(ActivationData result, string grainType)
        {
            var statefulGrain = result.GrainInstance as IStatefulGrain;
            if (statefulGrain == null)
            {
                return;
            }

            var state = statefulGrain.GrainState;

            if (result.StorageProvider != null && state != null)
            {
                var sw = Stopwatch.StartNew();
                var innerState = statefulGrain.GrainState.State;

                // Populate state data
                try
                {
                    var grainRef = result.GrainReference;

                    await scheduler.RunOrQueueTask(() =>
                        result.StorageProvider.ReadStateAsync(grainType, grainRef, state),
                        new SchedulingContext(result));

                    sw.Stop();
                    StorageStatisticsGroup.OnStorageActivate(result.StorageProvider, grainType, result.GrainReference, sw.Elapsed);
                }
                catch (Exception ex)
                {
                    StorageStatisticsGroup.OnStorageActivateError(result.StorageProvider, grainType, result.GrainReference);
                    sw.Stop();
                    if (!(ex.GetBaseException() is KeyNotFoundException))
                        throw;

                    statefulGrain.GrainState.State = innerState; // Just keep original empty state object
                }
            }
        }

        /// <summary>
        /// Try to get runtime data for an activation
        /// </summary>
        /// <param name="activationId"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool TryGetActivationData(ActivationId activationId, out ActivationData data)
        {
            data = null;
            if (activationId.IsSystem) return false;

            data = activations.FindTarget(activationId);
            return data != null;
        }

        private Task DeactivateActivationsFromCollector(List<ActivationData> list)
        {
            logger.Info(ErrorCode.Catalog_ShutdownActivations_1, "DeactivateActivationsFromCollector: total {0} to promptly Destroy.", list.Count);
            CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_COLLECTION).IncrementBy(list.Count);
            foreach (var activation in list)
            {
                lock (activation)
                {
                    activation.PrepareForDeactivation(); // Don't accept any new messages
                }
            }
            return DestroyActivations(list);
        }

        // To be called fro within Activation context.
        // Cannot be awaitable, since after DestroyActivation is done the activation is in Invalid state and cannot await any Task.
        internal void DeactivateActivationOnIdle(ActivationData data)
        {
            bool promptly = false;
            bool alreadBeingDestroyed = false;
            lock (data)
            {
                if (data.State == ActivationState.Valid)
                {
                    // Change the ActivationData state here, since we're about to give up the lock.
                    data.PrepareForDeactivation(); // Don't accept any new messages
                    ActivationCollector.TryCancelCollection(data);
                    if (!data.IsCurrentlyExecuting)
                    {
                        promptly = true;
                    }
                    else // busy, so destroy later.
                    {
                        data.AddOnInactive(() => DestroyActivationVoid(data));
                    }
                }
                else if (data.State == ActivationState.Create)
                {
                    throw new InvalidOperationException(String.Format(
                        "Activation {0} has called DeactivateOnIdle from within a constructor, which is not allowed.",
                            data.ToString()));
                }
                else if (data.State == ActivationState.Activating)
                {
                    throw new InvalidOperationException(String.Format(
                        "Activation {0} has called DeactivateOnIdle from within OnActivateAsync, which is not allowed.",
                            data.ToString()));
                }
                else
                {
                    alreadBeingDestroyed = true;
                }
            }
            logger.Info(ErrorCode.Catalog_ShutdownActivations_2,
                "DeactivateActivationOnIdle: {0} {1}.", data.ToString(), promptly ? "promptly" : (alreadBeingDestroyed ? "already being destroyed or invalid" : "later when become idle"));

            CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_DEACTIVATE_ON_IDLE).Increment();
            if (promptly)
            {
                DestroyActivationVoid(data); // Don't await or Ignore, since we are in this activation context and it may have alraedy been destroyed!
            }
        }

        /// <summary>
        /// Gracefully deletes activations, putting it into a shutdown state to
        /// complete and commit outstanding transactions before deleting it.
        /// To be called not from within Activation context, so can be awaited.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        internal async Task DeactivateActivations(List<ActivationData> list)
        {
            if (list == null || list.Count == 0) return;

            if (logger.IsVerbose) logger.Verbose("DeactivateActivations: {0} activations.", list.Count);
            List<ActivationData> destroyNow = null;
            List<MultiTaskCompletionSource> destroyLater = null;
            int alreadyBeingDestroyed = 0;
            foreach (var d in list)
            {
                var activationData = d; // capture
                lock (activationData)
                {
                    if (activationData.State == ActivationState.Valid)
                    {
                        // Change the ActivationData state here, since we're about to give up the lock.
                        activationData.PrepareForDeactivation(); // Don't accept any new messages
                        ActivationCollector.TryCancelCollection(activationData);
                        if (!activationData.IsCurrentlyExecuting)
                        {
                            if (destroyNow == null)
                            {
                                destroyNow = new List<ActivationData>();
                            }
                            destroyNow.Add(activationData);
                        }
                        else // busy, so destroy later.
                        {
                            if (destroyLater == null)
                            {
                                destroyLater = new List<MultiTaskCompletionSource>();
                            }
                            var tcs = new MultiTaskCompletionSource(1);
                            destroyLater.Add(tcs);
                            activationData.AddOnInactive(() => DestroyActivationAsync(activationData, tcs));
                        }
                    }
                    else
                    {
                        alreadyBeingDestroyed++;
                    }
                }
            }

            int numDestroyNow = destroyNow == null ? 0 : destroyNow.Count;
            int numDestroyLater = destroyLater == null ? 0 : destroyLater.Count;
            logger.Info(ErrorCode.Catalog_ShutdownActivations_3,
                "DeactivateActivations: total {0} to shutdown, out of them {1} promptly, {2} later when become idle and {3} are already being destroyed or invalid.",
                list.Count, numDestroyNow, numDestroyLater, alreadyBeingDestroyed);
            CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_SHUTDOWN_VIA_DIRECT_SHUTDOWN).IncrementBy(list.Count);

            if (destroyNow != null && destroyNow.Count > 0)
            {
                await DestroyActivations(destroyNow);
            }
            if (destroyLater != null && destroyLater.Count > 0)
            {
                await Task.WhenAll(destroyLater.Select(t => t.Task).ToArray());
            }
        }

        public Task DeactivateAllActivations()
        {
            logger.Info(ErrorCode.Catalog_DeactivateAllActivations, "DeactivateAllActivations.");
            var activationsToShutdown = activations.Where(kv => !kv.Value.IsExemptFromCollection).Select(kv => kv.Value).ToList();
            return DeactivateActivations(activationsToShutdown);
        }

        /// <summary>
        /// Deletes activation immediately regardless of active transactions etc.
        /// For use by grain delete, transaction abort, etc.
        /// </summary>
        /// <param name="activation"></param>
        private void DestroyActivationVoid(ActivationData activation)
        {
            StartDestroyActivations(new List<ActivationData> { activation });
        }

        private void DestroyActivationAsync(ActivationData activation, MultiTaskCompletionSource tcs)
        {
            StartDestroyActivations(new List<ActivationData> { activation }, tcs);
        }

        /// <summary>
        /// Forcibly deletes activations now, without waiting for any outstanding transactions to complete.
        /// Deletes activation immediately regardless of active transactions etc.
        /// For use by grain delete, transaction abort, etc.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        // Overall code flow:
        // Deactivating state was already set before, in the correct context under lock.
        //      that means no more new requests will be accepted into this activation and all timer were stopped (no new ticks will be delivered or enqueued)
        // Wait for all already scheduled ticks to finish
        // CallGrainDeactivate
        //      when AsyncDeactivate promise is resolved (NOT when all Deactivate turns are done, which may be orphan tasks):
        // Unregister in the directory
        //      when all AsyncDeactivate turns are done (Dispatcher.OnActivationCompletedRequest):
        // Set Invalid state
        // UnregisterMessageTarget -> no new tasks will be enqueue (if an orphan task get enqueud, it is ignored and dropped on the floor).
        // InvalidateCacheEntry
        // Reroute pending
        private Task DestroyActivations(List<ActivationData> list)
        {
            var tcs = new MultiTaskCompletionSource(list.Count);
            StartDestroyActivations(list, tcs);
            return tcs.Task;
        }

        private async void StartDestroyActivations(List<ActivationData> list, MultiTaskCompletionSource tcs = null)
        {
            int number = destroyActivationsNumber;
            destroyActivationsNumber++;
            try
            {
                logger.Info(ErrorCode.Catalog_DestroyActivations, "Starting DestroyActivations #{0} of {1} activations", number, list.Count);

                // step 1 - WaitForAllTimersToFinish
                var tasks1 = new List<Task>();
                foreach (var activation in list)
                {
                    tasks1.Add(activation.WaitForAllTimersToFinish());
                }

                try
                {
                    await Task.WhenAll(tasks1);
                }
                catch (Exception exc)
                {
                    logger.Warn(ErrorCode.Catalog_WaitForAllTimersToFinish_Exception, String.Format("WaitForAllTimersToFinish {0} failed.", list.Count), exc);
                }

                // step 2 - CallGrainDeactivate
                var tasks2 = new List<Tuple<Task, ActivationData>>();
                foreach (var activation in list)
                {
                    var activationData = activation; // Capture loop variable
                    var task = scheduler.RunOrQueueTask(() => CallGrainDeactivateAndCleanupStreams(activationData), new SchedulingContext(activationData));
                    tasks2.Add(new Tuple<Task, ActivationData>(task, activationData));
                }
                var asyncQueue = new AsyncBatchedContinuationQueue<ActivationData>();
                asyncQueue.Queue(tasks2, tupleList =>
                {
                    FinishDestroyActivations(tupleList.Select(t => t.Item2).ToList(), number, tcs);
                    GC.KeepAlive(asyncQueue); // not sure about GC not collecting the asyncQueue local var prematuraly, so just want to capture it here to make sure. Just to be safe.
                });
            }
            catch (Exception exc)
            {
                logger.Warn(ErrorCode.Catalog_DeactivateActivation_Exception, String.Format("StartDestroyActivations #{0} failed with {1} Activations.", number, list.Count), exc);
            }
        }

        private async void FinishDestroyActivations(List<ActivationData> list, int number, MultiTaskCompletionSource tcs)
        {
            try
            {
                //logger.Info(ErrorCode.Catalog_DestroyActivations_Done, "Starting FinishDestroyActivations #{0} - with {1} Activations.", number, list.Count);
                // step 3 - UnregisterManyAsync
                try
                {
                    List<ActivationAddress> activationsToDeactivate = list.
                        Where((ActivationData d) => d.IsUsingGrainDirectory).
                        Select((ActivationData d) => ActivationAddress.GetAddress(LocalSilo, d.Grain, d.ActivationId)).ToList();

                    if (activationsToDeactivate.Count > 0)
                    {
                        await scheduler.RunOrQueueTask(() =>
                            directory.UnregisterManyAsync(activationsToDeactivate),
                            SchedulingContext);
                    }
                }
                catch (Exception exc)
                {
                    logger.Warn(ErrorCode.Catalog_UnregisterManyAsync, String.Format("UnregisterManyAsync {0} failed.", list.Count), exc);
                }

                // step 4 - UnregisterMessageTarget and OnFinishedGrainDeactivate
                foreach (var activationData in list)
                {
                    try
                    {
                        lock (activationData)
                        {
                            activationData.SetState(ActivationState.Invalid); // Deactivate calls on this activation are finished
                        }
                        UnregisterMessageTarget(activationData);
                    }
                    catch (Exception exc)
                    {
                        logger.Warn(ErrorCode.Catalog_UnregisterMessageTarget2, String.Format("UnregisterMessageTarget failed on {0}.", activationData), exc);
                    }
                    try
                    {
                        // IMPORTANT: no more awaits and .Ignore after that point.

                        // Just use this opportunity to invalidate local Cache Entry as well.
                        // If this silo is not the grain directory partition for this grain, it may have it in its cache.
                        directory.InvalidateCacheEntry(activationData.Address);

                        RerouteAllQueuedMessages(activationData, null, "Finished Destroy Activation");
                    }
                    catch (Exception exc)
                    {
                        logger.Warn(ErrorCode.Catalog_UnregisterMessageTarget3, String.Format("Last stage of DestroyActivations failed on {0}.", activationData), exc);
                    }
                }
                // step 5 - Resolve any waiting TaskCompletionSource
                if (tcs != null)
                {
                    tcs.SetMultipleResults(list.Count);
                }
                logger.Info(ErrorCode.Catalog_DestroyActivations_Done, "Done FinishDestroyActivations #{0} - Destroyed {1} Activations.", number, list.Count);
            }catch (Exception exc)
            {
                logger.Error(ErrorCode.Catalog_FinishDeactivateActivation_Exception, String.Format("FinishDestroyActivations #{0} failed with {1} Activations.", number, list.Count), exc);
            }
        }
        private void RerouteAllQueuedMessages(ActivationData activation, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            lock (activation)
            {
                List<Message> msgs = activation.DequeueAllWaitingMessages();
                if (msgs == null || msgs.Count <= 0) return;

                if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_RerouteAllQueuedMessages, String.Format("RerouteAllQueuedMessages: {0} msgs from Invalid activation {1}.", msgs.Count(), activation));
                dispatcher.ProcessRequestsToInvalidActivation(msgs, activation.Address, forwardingAddress, failedOperation, exc);
            }
        }

        private async Task CallGrainActivate(ActivationData activation, Dictionary<string, object> requestContextData)
        {
            var grainTypeName = activation.GrainInstanceType.FullName;

            // Note: This call is being made from within Scheduler.Queue wrapper, so we are already executing on worker thread
            if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_BeforeCallingActivate, "About to call {1} grain's OnActivateAsync() method {0}", activation, grainTypeName);

            // Call OnActivateAsync inline, but within try-catch wrapper to safely capture any exceptions thrown from called function
            try
            {
                RequestContext.Import(requestContextData);
                await activation.GrainInstance.OnActivateAsync();

                if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_AfterCallingActivate, "Returned from calling {1} grain's OnActivateAsync() method {0}", activation, grainTypeName);

                lock (activation)
                {
                    if (activation.State == ActivationState.Activating)
                    {
                        activation.SetState(ActivationState.Valid); // Activate calls on this activation are finished
                    }
                    if (!activation.IsCurrentlyExecuting)
                    {
                        activation.RunOnInactive();
                    }
                    // Run message pump to see if there is a new request is queued to be processed
                    dispatcher.RunMessagePump(activation);
                }
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.Catalog_ErrorCallingActivate,
                    string.Format("Error calling grain's OnActivateAsync() method - Grain type = {1} Activation = {0}", activation, grainTypeName), exc);

                activation.SetState(ActivationState.Invalid); // Mark this activation as unusable

                activationsFailedToActivate.Increment();

                throw;
            }
        }

        private async Task<ActivationData> CallGrainDeactivateAndCleanupStreams(ActivationData activation)
        {
            try
            {
                var grainTypeName = activation.GrainInstanceType.FullName;

                // Note: This call is being made from within Scheduler.Queue wrapper, so we are already executing on worker thread
                if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_BeforeCallingDeactivate, "About to call {1} grain's OnDeactivateAsync() method {0}", activation, grainTypeName);

                // Call OnDeactivateAsync inline, but within try-catch wrapper to safely capture any exceptions thrown from called function
                try
                {
                    // just check in case this activation data is already Invalid or not here at all.
                    ActivationData ignore;
                    if (TryGetActivationData(activation.ActivationId, out ignore) &&
                        activation.State == ActivationState.Deactivating)
                    {
                        RequestContext.Clear(); // Clear any previous RC, so it does not leak into this call by mistake.
                        await activation.GrainInstance.OnDeactivateAsync();
                    }
                    if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_AfterCallingDeactivate, "Returned from calling {1} grain's OnDeactivateAsync() method {0}", activation, grainTypeName);
                }
                catch (Exception exc)
                {
                    logger.Error(ErrorCode.Catalog_ErrorCallingDeactivate,
                        string.Format("Error calling grain's OnDeactivateAsync() method - Grain type = {1} Activation = {0}", activation, grainTypeName), exc);
                }

                if (activation.IsUsingStreams)
                {
                    try
                    {
                        await activation.DeactivateStreamResources();
                    }
                    catch (Exception exc)
                    {
                        logger.Warn(ErrorCode.Catalog_DeactivateStreamResources_Exception, String.Format("DeactivateStreamResources Grain type = {0} Activation = {1} failed.", grainTypeName, activation), exc);
                    }
                }
            }
            catch(Exception exc)
            {
                logger.Error(ErrorCode.Catalog_FinishGrainDeactivateAndCleanupStreams_Exception, String.Format("CallGrainDeactivateAndCleanupStreams Activation = {0} failed.", activation), exc);
            }
            return activation;
        }

        private async Task RegisterActivationInGrainDirectoryAndValidate(ActivationData activation)
        {
            ActivationAddress address = activation.Address;
            // Currently, the only grain type that is not registered in the Grain Directory is StatelessWorker.
            // Among those that are registered in the directory, we currently do not have any multi activations.
            if (activation.IsUsingGrainDirectory)
            {

                var result = await scheduler.RunOrQueueTask(() => directory.RegisterAsync(address, singleActivation:true), this.SchedulingContext);
                if (address.Equals(result.Address)) return;

                SiloAddress primaryDirectoryForGrain = directory.GetPrimaryForGrain(address.Grain);
                throw new DuplicateActivationException(result.Address, primaryDirectoryForGrain);
            }
            else
            {
                StatelessWorkerPlacement stPlacement = activation.PlacedUsing as StatelessWorkerPlacement;
                int maxNumLocalActivations = stPlacement.MaxLocal;
                lock (activations)
                {
                    List<ActivationData> local;
                    if (!LocalLookup(address.Grain, out local) || local.Count <= maxNumLocalActivations)
                        return;

                    var id = StatelessWorkerDirector.PickRandom(local).Address;
                    throw new DuplicateActivationException(id);
                }
            }
            // We currently don't have any other case for multiple activations except for StatelessWorker.
        }

        #endregion
        #region Activations - private

        /// <summary>
        /// Invoke the activate method on a newly created activation
        /// </summary>
        /// <param name="activation"></param>
        /// <param name="requestContextData"></param>
        /// <returns></returns>
        private Task InvokeActivate(ActivationData activation, Dictionary<string, object> requestContextData)
        {
            // NOTE: This should only be called with the correct schedulering context for the activation to be invoked.
            lock (activation)
            {
                activation.SetState(ActivationState.Activating);
            }
            return scheduler.QueueTask(() => CallGrainActivate(activation, requestContextData), new SchedulingContext(activation)); // Target grain's scheduler context);
            // ActivationData will transition out of ActivationState.Activating via Dispatcher.OnActivationCompletedRequest
        }
        #endregion
        #region IPlacementContext

        public Logger Logger => logger;

        public bool FastLookup(GrainId grain, out AddressesAndTag addresses)
        {
            return directory.LocalLookup(grain, out addresses) && addresses.Addresses != null && addresses.Addresses.Count > 0;
            // NOTE: only check with the local directory cache.
            // DO NOT check in the local activations TargetDirectory!!!
            // The only source of truth about which activation should be legit to is the state of the ditributed directory.
            // Everyone should converge to that (that is the meaning of "eventualy consistency - eventualy we converge to one truth").
            // If we keep using the local activation, it may not be registered in th directory any more, but we will never know that and keep using it,
            // thus volaiting the single-activation semantics and not converging even eventualy!
        }

        public Task<AddressesAndTag> FullLookup(GrainId grain)
        {
            return scheduler.RunOrQueueTask(() => directory.LookupAsync(grain), this.SchedulingContext);
        }

        public bool LocalLookup(GrainId grain, out List<ActivationData> addresses)
        {
            addresses = activations.FindTargets(grain);
            return addresses != null;
        }

        public List<SiloAddress> AllActiveSilos
        {
            get
            {
                var result = SiloStatusOracle.GetApproximateSiloStatuses(true).Select(s => s.Key).ToList();
                if (result.Count > 0) return result;

                logger.Warn(ErrorCode.Catalog_GetApproximateSiloStatuses, "AllActiveSilos SiloStatusOracle.GetApproximateSiloStatuses empty");
                return new List<SiloAddress> { LocalSilo };
            }
        }

        #endregion
        #region Implementation of ICatalog

        public Task CreateSystemGrain(GrainId grainId, string grainType)
        {
            ActivationAddress target = ActivationAddress.NewActivationAddress(LocalSilo, grainId);
            Task activatedPromise;
            GetOrCreateActivation(target, true, grainType, null, null, out activatedPromise);
            return activatedPromise ?? TaskDone.Done;
        }

        public Task DeleteActivations(List<ActivationAddress> addresses)
        {
            return DestroyActivations(TryGetActivationDatas(addresses));
        }

        private List<ActivationData> TryGetActivationDatas(List<ActivationAddress> addresses)
        {
            var datas = new List<ActivationData>(addresses.Count);
            foreach (var activationAddress in addresses)
            {
                ActivationData data;
                if (TryGetActivationData(activationAddress.Activation, out data))
                    datas.Add(data);
            }
            return datas;
        }

        #endregion

        #region Implementation of ISiloStatusListener

        public void SiloStatusChangeNotification(SiloAddress updatedSilo, SiloStatus status)
        {
            // ignore joining events and also events on myself.
            if (updatedSilo.Equals(LocalSilo)) return;

            // We deactivate those activations when silo goes either of ShuttingDown/Stopping/Dead states,
            // since this is what Directory is doing as well. Directory removes a silo based on all those 3 statuses,
            // thus it will only deliver a "remove" notification for a given silo once to us. Therefore, we need to react the fist time we are notified.
            // We may review the directory behaiviour in the future and treat ShuttingDown differently ("drain only") and then this code will have to change a well.
            if (!status.IsTerminating()) return;
            if (status == SiloStatus.Dead)
            {
                RuntimeClient.Current.BreakOutstandingMessagesToDeadSilo(updatedSilo);
            }

            var activationsToShutdown = new List<ActivationData>();
            try
            {
                // scan all activations in activation directory and deactivate the ones that the removed silo is their primary partition owner.
                lock (activations)
                {
                    foreach (var activation in activations)
                    {
                        try
                        {
                            var activationData = activation.Value;
                            if (!activationData.IsUsingGrainDirectory) continue;
                            if (!directory.GetPrimaryForGrain(activationData.Grain).Equals(updatedSilo)) continue;

                            lock (activationData)
                            {
                                // adapted from InsideGarinClient.DeactivateOnIdle().
                                activationData.ResetKeepAliveRequest();
                                activationsToShutdown.Add(activationData);
                            }
                        }
                        catch (Exception exc)
                        {
                            logger.Error(ErrorCode.Catalog_SiloStatusChangeNotification_Exception,
                                String.Format("Catalog has thrown an exception while executing SiloStatusChangeNotification of silo {0}.", updatedSilo.ToStringWithHashCode()), exc);
                        }
                    }
                }
                logger.Info(ErrorCode.Catalog_SiloStatusChangeNotification,
                    String.Format("Catalog is deactivating {0} activations due to a failure of silo {1}, since it is a primary directory partiton to these grain ids.",
                        activationsToShutdown.Count, updatedSilo.ToStringWithHashCode()));
            }
            finally
            {
                // outside the lock.
                if (activationsToShutdown.Count > 0)
                {
                    DeactivateActivations(activationsToShutdown).Ignore();
                }
            }
        }

        #endregion
    }
}


text:
<?xml version="1.0" encoding="ISO-8859-1"?>
<igsSiteLog xmlns="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/2004" xmlns:contact="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/contact/2004" xmlns:equip="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/equipment/2004" xmlns:li="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/localInterferences/2004" xmlns:mi="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/monumentInfo/2004" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/2004  http://sopac.ucsd.edu/ns/geodesy/doc/igsSiteLog/2004/igsSiteLog.xsd"><!--Alice Springs Station Log-->
<!--Version 0.01-->
<!--Geoscience Australia Geodesy-->
<!--For More Information regarding XML based Site Logs go to-->
<!--http://sopac.ucsd.edu/projects/xml-->

  <formInformation>
    <mi:preparedBy>Manoj Deo</mi:preparedBy>
    <mi:datePrepared>2010-05-05</mi:datePrepared>
    <mi:reportType>UPDATE</mi:reportType>
    <mi:previousLog></mi:previousLog>
    <mi:modifiedSections></mi:modifiedSections>
  </formInformation>
  <siteIdentification>
    <mi:siteName>Lyttelton Tide Gauge</mi:siteName>
    <mi:fourCharacterID>LYTT</mi:fourCharacterID>
    <mi:monumentInscription></mi:monumentInscription>
    <mi:iersDOMESNumber>50214S001</mi:iersDOMESNumber>
    <mi:cdpNumber>n/a</mi:cdpNumber>
    <mi:monumentDescription></mi:monumentDescription>
    <mi:heightOfTheMonument></mi:heightOfTheMonument>
    <mi:monumentFoundation></mi:monumentFoundation>
    <mi:foundationDepth></mi:foundationDepth>
    <mi:markerDescription></mi:markerDescription>
    <mi:dateInstalled>1999-11-15T00</mi:dateInstalled>
    <mi:geologicCharacteristic></mi:geologicCharacteristic>
    <mi:bedrockType></mi:bedrockType>
    <mi:bedrockCondition></mi:bedrockCondition>
    <mi:fractureSpacing></mi:fractureSpacing>
    <mi:faultZonesNearby></mi:faultZonesNearby>
    <mi:distance-Activity></mi:distance-Activity>
    <mi:notes></mi:notes>
  </siteIdentification>
  <siteLocation>
    <mi:city></mi:city>
    <mi:state></mi:state>
    <mi:country>New Zealand</mi:country>
    <mi:tectonicPlate></mi:tectonicPlate>
    <approximatePositionITRF>
      <mi:xCoordinateInMeters>-4588535.8900</mi:xCoordinateInMeters>
      <mi:yCoordinateInMeters>585995.9500</mi:yCoordinateInMeters>
      <mi:zCoordinateInMeters>-4376497.2100</mi:zCoordinateInMeters>
      <mi:latitude-North></mi:latitude-North>
      <mi:longitude-East></mi:longitude-East>
      <mi:elevation-m_ellips.>(m)</mi:elevation-m_ellips.>
    </approximatePositionITRF>
    <mi:notes>(multiple lines)</mi:notes>
  </siteLocation>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion></equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>1999-11-14T11:00Z</equip:dateInstalled>
    <equip:dateRemoved>2000-02-29T11:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion>unknown</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2000-02-29T11:00Z</equip:dateInstalled>
    <equip:dateRemoved>2000-07-22T12:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion>4.42</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2000-07-22T12:00Z</equip:dateInstalled>
    <equip:dateRemoved>2000-08-16T12:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion>6.21</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2000-08-16T12:00Z</equip:dateInstalled>
    <equip:dateRemoved>2000-12-26T11:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion>8.02</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2000-12-26T11:00Z</equip:dateInstalled>
    <equip:dateRemoved>2002-07-04T12:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA CRS1000</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>23199</equip:serialNumber>
    <equip:firmwareVersion>9.00</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2002-07-04T12:00Z</equip:dateInstalled>
    <equip:dateRemoved>2003-11-23T11:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA RS500</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>82242</equip:serialNumber>
    <equip:firmwareVersion>9.00</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2003-11-23T11:00Z</equip:dateInstalled>
    <equip:dateRemoved>2007-09-25T12:00Z</equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssReceiver>
    <equip:receiverType>LEICA GRX1200GGPRO</equip:receiverType>
    <equip:satelliteSystem>GPS</equip:satelliteSystem>
    <equip:serialNumber>353205</equip:serialNumber>
    <equip:firmwareVersion>5.10/3.013</equip:firmwareVersion>
    <equip:elevationCutoffSetting>0</equip:elevationCutoffSetting>
    <equip:dateInstalled>2007-09-25T12:00Z</equip:dateInstalled>
    <equip:dateRemoved></equip:dateRemoved>
    <equip:temperatureStabilization>none</equip:temperatureStabilization>
    <equip:notes>(multiple lines)</equip:notes>
  </gnssReceiver>
  <gnssAntenna>
    <equip:antennaType>LEIAT504        LEIS</equip:antennaType>
    <equip:serialNumber>405</equip:serialNumber>
    <equip:antennaReferencePoint>BPA</equip:antennaReferencePoint>
    <equip:marker-arpUpEcc.>000.0010</equip:marker-arpUpEcc.>
    <equip:marker-arpNorthEcc.>000.0000</equip:marker-arpNorthEcc.>
    <equip:marker-arpEastEcc.>000.0000</equip:marker-arpEastEcc.>
    <equip:alignmentFromTrueNorth>0</equip:alignmentFromTrueNorth>
    <equip:antennaRadomeType>LEIS</equip:antennaRadomeType>
    <equip:radomeSerialNumber></equip:radomeSerialNumber>
    <equip:antennaCableType></equip:antennaCableType>
    <equip:antennaCableLength>0</equip:antennaCableLength>
    <equip:dateInstalled>1999-11-14T11:00Z</equip:dateInstalled>
    <equip:dateRemoved></equip:dateRemoved>
    <equip:notes></equip:notes>
  </gnssAntenna>
  <frequencyStandard>
    <equip:standardType>QUARTZ/INTERNAL</equip:standardType>
    <equip:inputFrequency></equip:inputFrequency>
    <equip:effectiveDates>1999-11-14/(CCYY-MM-DD)</equip:effectiveDates>
    <equip:notes>(multiple lines)</equip:notes>
  </frequencyStandard>
  <radioInterferences>
    <li:possibleProblemSources>(TV/CELL PHONE ANTENNA/RADAR/etc)</li:possibleProblemSources>
    <li:effectiveDates>(CCYY-MM-DD/CCYY-MM-DD)</li:effectiveDates>
    <li:observedDegredation></li:observedDegredation>
    <li:notes>(multiple lines)</li:notes>
  </radioInterferences>
  <contactAgency>
    <contact:agency>(multiple lines)</contact:agency>
    <contact:preferredAbbreviation></contact:preferredAbbreviation>
    <contact:mailingAddress>(multiple lines)</contact:mailingAddress>
    <contact:primaryContact>
      <contact:name></contact:name>
      <contact:telephonePrimary></contact:telephonePrimary>
      <contact:telephoneSecondary></contact:telephoneSecondary>
      <contact:fax></contact:fax>
      <contact:e-mail></contact:e-mail>
    </contact:primaryContact>
    <contact:secondaryContact>
      <contact:name></contact:name>
      <contact:telephonePrimary></contact:telephonePrimary>
      <contact:telephoneSecondary></contact:telephoneSecondary>
      <contact:fax></contact:fax>
      <contact:e-mail></contact:e-mail>
    </contact:secondaryContact>
    <contact:notes>(multiple lines)</contact:notes>
  </contactAgency>
  <responsibleAgency>
    <contact:agency>(multiple lines)</contact:agency>
    <contact:preferredAbbreviation></contact:preferredAbbreviation>
    <contact:mailingAddress>(multiple lines)</contact:mailingAddress>
    <contact:primaryContact>
      <contact:name></contact:name>
      <contact:telephonePrimary></contact:telephonePrimary>
      <contact:telephoneSecondary></contact:telephoneSecondary>
      <contact:fax></contact:fax>
      <contact:e-mail></contact:e-mail>
    </contact:primaryContact>
    <contact:secondaryContact>
      <contact:name></contact:name>
      <contact:telephonePrimary></contact:telephonePrimary>
      <contact:telephoneSecondary></contact:telephoneSecondary>
      <contact:fax></contact:fax>
      <contact:e-mail></contact:e-mail>
    </contact:secondaryContact>
    <contact:notes>(multiple lines)</contact:notes>
  </responsibleAgency>
  <moreInformation>
    <mi:primaryDataCenter></mi:primaryDataCenter>
    <mi:secondaryDataCenter></mi:secondaryDataCenter>
    <mi:urlForMoreInformation></mi:urlForMoreInformation>
    <mi:hardCopyOnFile/>
    <mi:siteMap>Y</mi:siteMap>
    <mi:siteDiagram>Y</mi:siteDiagram>
    <mi:horizonMask>Y</mi:horizonMask>
    <mi:monumentDescription></mi:monumentDescription>
    <mi:sitePictures>Y</mi:sitePictures>
    <mi:notes>(multiple lines)</mi:notes>
    <mi:antennaGraphicsWithDimensions/>
    <mi:insertTextGraphicFromAntenna/>
  </moreInformation>
</igsSiteLog>

redpajama_set_name: RedPajamaGithub


text:
package org.apache.hadoop.hbase.mapred;

import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.util.ProgramDriver;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

@Category(SmallTests.class)
public class TestDriver {

  @Test
  @SuppressWarnings("deprecation")
  public void testDriverMainMethod() throws Throwable {
    ProgramDriver programDriverMock = mock(ProgramDriver.class);
    Driver.setProgramDriver(programDriverMock);
    Driver.main(new String[]{});
    verify(programDriverMock).driver(Mockito.any(String[].class));
  }
}


text:
<!--
  #%L
  %%
  Copyright (C) 2011 - 2017 BMW Car IT GmbH
  %%
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  #L%
  -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>io.joynr.tests</groupId>
	<artifactId>system-integration-test</artifactId>
	<name>${project.groupId}:${project.artifactId}</name>
	<packaging>pom</packaging>

	<parent>
		<groupId>io.joynr</groupId>
		<artifactId>tests</artifactId>
		<version>1.21.6</version>
	</parent>

	<modules>
		<module>sit-cpp-app</module>
		<module>sit-java-app</module>
		<module>sit-jee-api</module>
		<module>sit-jee-app</module>
		<module>sit-jee-stateless-consumer</module>
		<module>sit-node-app</module>
		<module>sit-controller</module>
	</modules>

	<build>
		<resources>
			<resource>
				<directory>src/main/model</directory>
			</resource>
		</resources>
	</build>
</project>


text:
package com.tuenti.gourmet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.tuenti.gourmet.models.Restaurant;
import com.tuenti.gourmet.models.Subscription;
import com.tuenti.gourmet.repositories.Repository.Callback;
import com.tuenti.gourmet.repositories.RestaurantRepository;
import com.tuenti.gourmet.repositories.SubscriptionRepository;

/**
 * Created by gmerino on 11/03/16.
 */
public class SubscriptionsListPresenter implements Callback<Subscription> {

	private View view;
	private List<Subscription> subscriptions;

	@Override
	public void onDataChange(List<Subscription> items) {
	}

	public interface View {
		void onSubscriptionsChanged(List<Subscription> subscriptions);
	}

	public void init(View view) {
		this.view = view;
	}

	public void onResume() {
		List<Subscription> subscriptionsTemp = new ArrayList<>();
		Set<String> subscriptionNames = SubscriptionRepository.getInstance().getSubscriptions();

		List<Restaurant> restaurantList = RestaurantRepository.getInstance().getItems();

		for (Restaurant restaurant : restaurantList) {
			subscriptionsTemp.add(new Subscription(restaurant, subscriptionNames.contains(restaurant.getName())));
		}

		subscriptions = subscriptionsTemp;

		view.onSubscriptionsChanged(subscriptions);
	}

	public void onPause() {
		SubscriptionRepository.getInstance().reset();
		for (Subscription subscription : subscriptions) {
			if (subscription.isSubscribed()) {
				SubscriptionRepository.getInstance().post(subscription.getRestaurant().getName());
			}
		}

	}
}


text:
module Policycatalog
  class Application < Rails::Application
    #config.middleware.delete
    #config.middleware.use
  end
end


text:
require_relative 'scope/base'
require_relative 'scope_actor'

module Aygabtu
  class ScopeChain
    def initialize(example_group, scope)
      @example_group = example_group
      @scope = scope
    end

    attr_reader :scope

    Scope::Base.factory_methods.each do |factory_method|
      define_method(factory_method) do |*args, &block|
        new_scope = @scope.public_send(factory_method, *args)

        result = self.class.new(@example_group, new_scope)

        @example_group.aygabtu_enter_context(block, new_scope) if block

        result
      end
    end

    def remaining(&block)
      remaining_at(@example_group.aygabtu_handle.checkpoint, &block)
    end

    def self.scope_methods
      [:remaining, *Scope::Base.factory_methods]
    end

    ScopeActor.actions.each do |action|
      define_method(action) do |*args|
        @example_group.aygabtu_action(action, @scope, *args)
      end
    end
  end
end


text:
[![Build Status](https://travis-ci.org/firebase/FirebaseUI-Android.svg?branch=master)](https://travis-ci.org/firebase/FirebaseUI-Android)

FirebaseUI is an open-source library for Android that allows you to
quickly connect common UI elements to [Firebase](https://firebase.google.com)
APIs like the Realtime Database or Firebase Authentication.

A compatible FirebaseUI client is also available for [iOS](https://github.com/firebase/firebaseui-ios).

## Table of Content

  1. [Installation](#installation)
  1. [Usage](#usage)
  1. [Sample App](#sample-app)
  1. [Contributing](#contributing)

## Installation

FirebaseUI is published as a collection of libraries separated by the
Firebase API they target. Each FirebaseUI library has a transitive
dependency on the appropriate Firebase SDK so there is no need to include
those separately in your app.

In your `app/build.gradle` file add a dependency on one of the FirebaseUI
libraries.

```groovy
dependencies {
    // Single target that includes all FirebaseUI libraries
    compile 'com.firebaseui:firebase-ui:0.5.3'

    // FirebaseUI Database only
    compile 'com.firebaseui:firebase-ui-database:0.5.3'

    // FirebaseUI Auth only
    compile 'com.firebaseui:firebase-ui-auth:0.5.3'
}
```

After the project is synchronized, we're ready to start using Firebase functionality in our app.

### Compatibility with Firebase / Google Play Services Libraries

FirebaseUI libraries have the following transitive dependencies on the Firebase SDK:
```
firebase-ui-auth
|--- com.google.firebase:firebase-auth
|--- com.google.android.gms:play-services-auth

firebase-ui-database
|--- com.google.firebase:firebase-database
```

Each version of FirebaseUI has dependency on a fixed version of these libraries, defined as the variable `firebase_version`
in `common/constants.gradle`.  If you are using any dependencies in your app of the form
`compile 'com.google.firebase:firebase-*:x.y.z'` or `compile 'com.google.android.gms:play-services-*:x.y.z'`
you need to make sure that you use the same version that your chosen version of FirebaseUI requires.

For convenience, here are some examples:

| FirebaseUI Version | Firebase/Play Services Version |
|--------------------|--------------------------------|
| 0.5.3              | 9.4.0                          |
| 0.4.4              | 9.4.0                          |
| 0.4.3              | 9.2.1                          |
| 0.4.2              | 9.2.0                          |
| 0.4.1              | 9.0.2                          |
| 0.4.0              | 9.0.0                          |

## Usage

  * [firebase-ui-database](database/README.md)
  * [firebase-ui-auth](auth/README.md)

## Sample App

There is a sample app in the `app/` directory that demonstrates most
of the features of FirebaseUI. Load the project in Android Studio and
run it on your Android device to see a demonstration.

## Contributing

### Installing locally

You can download FirebaseUI and install it locally by cloning this
repository and running:

    ./gradlew :library:prepareArtifacts :library:publishAllToMavenLocal

###  Deployment

To deploy FirebaseUI to Bintray

  1. Set `BINTRAY_USER` and `BINTRAY_KEY` in your environment. You must
     be a member of the firebaseui Bintray organization.
  1. Run `./gradlew clean :library:prepareArtifacts :library:bintrayUploadAll`
  1. Go to the Bintray dashboard and click 'Publish'.
    1. In Bintray click the 'Maven Central' tab and publish the release.

### Tag a release on GitHub

* Ensure that all your changes are on master and that your local build is on master
* Ensure that the correct version number is in `common/constants.gradle`

### Contributor License Agreements

We'd love to accept your sample apps and patches! Before we can take them, we
have to jump a couple of legal hurdles.

Please fill out either the individual or corporate Contributor License Agreement
(CLA).

  * If you are an individual writing original source code and you're sure you
    own the intellectual property, then you'll need to sign an
    [individual CLA](https://developers.google.com/open-source/cla/individual).
  * If you work for a company that wants to allow you to contribute your work,
    then you'll need to sign a
    [corporate CLA](https://developers.google.com/open-source/cla/corporate).

Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.

### Contribution Process

1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a
   Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style of the library to which
   you are contributing.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request and cc @puf or @samtstern


text:
require 'cerberus/constants'
require 'cerberus/utils'
require 'erb'

module Cerberus
  class Config
    def initialize(app_name = nil, cli_options = {})
      @config = HashWithIndifferentAccess.new
      if app_name
        merge!(YAML.load(ERB.new(IO.read(CONFIG_FILE)).result)) if test(?f, CONFIG_FILE)
        merge!(YAML.load(ERB.new(IO.read(HOME + "/config/#{app_name}.yml")).result))
      end
      merge!(cli_options)
    end

    def [](*path)
      c = @config
      path.each{|p|
        c = c[p]
        return if c.nil?
      }
      c
    end

    def merge!(hash, overwrite = true)
      if overwrite
        @config.deep_merge!(hash)
      else
        d = HashWithIndifferentAccess.new(hash)
        d.deep_merge!(@config)
        @config = d
      end
    end

    def inspect
      @config.inspect
    end

    private
    def symbolize_hash(hash)
      hash.each_pair{|k,v|
        if v === Hash
          hash[k] = HashWithIndifferentAccess.new(symbolize_hash(v))
        end
      }
    end
  end
end


text:
i18n_interpolation_spec
=======================

[![Circle CI](https://circleci.com/gh/creasty/i18n_interpolation_spec/tree/master.svg?style=svg)](https://circleci.com/gh/creasty/i18n_interpolation_spec/tree/master)

**i18n_interpolation_spec provides RSpec matchers for testing the completeness of interpolation arguments in locale files.**

It's great to use with [tigrish/i18n-spec](https://github.com/tigrish/i18n-spec).

Installation
------------

Add the gem to your Gemfile.

```ruby
gem 'i18n_interpolation_spec', group: :test
```

Matchers
--------

```ruby
describe 'config/locales/fr.yml' do
  it { is_expected.to be_a_complete_interpolation_of 'config/locales/en.yml' }
end

describe 'config/locales/it.yml' do
  it { is_expected.to have_mutual_interpolation_of 'config/locales/en.yml' }
end

describe 'config/locales/es.yml' do
  it {
    is_expected.to be_a_complete_interpolation_of 'config/locales/en.yml',
      except: [
        'some.key.to.ignore',
        /^some\.patt[e3]rn\.to\.ignore/,
      ]
  }
end
```

License
-------

This project is copyright by [Creasty](http://creasty.com), released under the MIT license.
See `LICENSE` file for details.


text:
/**
 * Test comment
 */
export enum SUIButtonState {
    DEFAULT = <any>'default',
    ACTIVE = <any>'active',
    DISABLED = <any>'disabled',
    LOADING = <any>'loading'
};


text:
package com.facebook.buck.features.ocaml;

import com.facebook.buck.core.exceptions.BuckUncheckedExecutionException;
import com.facebook.buck.core.filesystems.RelPath;
import com.facebook.buck.core.model.BuildTarget;
import com.facebook.buck.core.model.impl.BuildTargetPaths;
import com.facebook.buck.core.sourcepath.SourcePath;
import com.facebook.buck.core.sourcepath.resolver.SourcePathResolverAdapter;
import com.facebook.buck.core.util.log.Logger;
import com.facebook.buck.io.filesystem.ProjectFilesystem;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Predicate;

/** Utility functions */
public class OcamlUtil {
  private static final Logger LOG = Logger.get(OcamlUtil.class);

  private OcamlUtil() {}

  /**
   * Constructs a Predicate instance which returns true if the input argument ends with any String
   * in extensions
   *
   * @param extensions for which to return true
   * @return a Predicate instance
   */
  public static Predicate<? super Path> ext(String... extensions) {
    return (Predicate<Path>)
        input -> {
          String strInput = input.toString();
          for (String ext : extensions) {
            if (strInput.endsWith(ext)) {
              return true;
            }
          }
          return false;
        };
  }

  public static Predicate<? super SourcePath> sourcePathExt(
      SourcePathResolverAdapter resolver, String... extensions) {
    return (Predicate<SourcePath>)
        input -> {
          String strInput = resolver.getCellUnsafeRelPath(input).toString();
          for (String ext : extensions) {
            if (strInput.endsWith(ext)) {
              return true;
            }
          }
          return false;
        };
  }

  /** Creates a file path for a linker arg file. */
  public static RelPath makeLinkerArgFilePath(
      ProjectFilesystem filesystem, BuildTarget buildTarget) {
    return makeArgFilePath(filesystem, buildTarget, "cclib");
  }

  /** Creates a file path for an arg file */
  public static RelPath makeArgFilePath(
      ProjectFilesystem filesystem, BuildTarget buildTarget, String prefix) {
    String scratchFileName = String.format("%s.argfile", prefix);

    // NOTE: the single %s format placeholder is required by the getScratchPath method
    String scratchFileNameFormat = "%s" + scratchFileName;
    return BuildTargetPaths.getScratchPath(filesystem, buildTarget, scratchFileNameFormat);
  }

  /** Creates an arg file with a given list of flags */
  public static ImmutableList<String> makeArgFile(
      ProjectFilesystem filesystem,
      Path argFile,
      ImmutableList<String> toolPrefix,
      String flag,
      Iterable<String> flagList) {
    ImmutableList<String> immutableFlags;

    try {
      LOG.verbose("The flags file content is %s", flagList);
      LOG.info("The temporary flags file is %s", argFile.toString());

      Path parent = argFile.getParent();
      LOG.info("The parent path is %s", parent);

      filesystem.mkdirs(parent);

      Path fileName = argFile.getFileName();
      LOG.info("The file name is %s", fileName.toString());

      argFile = filesystem.createTempFile(parent, fileName.toString(), ".flags");

      filesystem.writeLinesToPath(flagList, argFile);
      LOG.info("Wrote the flags to path %s", argFile.toString());

      immutableFlags = ImmutableList.of("-" + flag, "@" + argFile.toString());
    } catch (IOException ioe) {
      LOG.error("Couldn't create an arg file.");
      throw new BuckUncheckedExecutionException(ioe, "When creating arg file at %s", argFile);
    }

    LOG.info(
        "The '%s' flags: '%s'",
        Joiner.on(' ').join(toolPrefix), Joiner.on(' ').join(immutableFlags));

    return immutableFlags;
  }

  static ImmutableSet<Path> getExtensionVariants(Path output, String... extensions) {
    String withoutExtension = stripExtension(output.toString());
    ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
    for (String ext : extensions) {
      builder.add(Paths.get(withoutExtension + ext));
    }
    return builder.build();
  }

  static String stripExtension(String fileName) {
    int index = fileName.lastIndexOf('.');

    // if dot is in the first position,
    // we are dealing with a hidden file rather than an extension
    return (index > 0) ? fileName.substring(0, index) : fileName;
  }
}


text:
<?php
// src/Sylius/Bundle/CoreBundle/Validator/Constraints/ContainsAlphanumericValidator.php
namespace Sylius\Bundle\CoreBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class IsTrueValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!$value) {
            $this->context->addViolation(
                $constraint->message
            );
        }
    }
}


text:
var through = require("through");

// The callback to be used on 'data' event
function write(chunk) {
    console.log("got %d bytes of data", chunk.length);
}

// The callback to be used on 'end' event
function end() {
    console.log("End Of Stream");
}

// Pipe it out!!!
process.stdin.pipe(through(write, end));


text:
<?php include_once('../app/view/include/header.inc.php'); ?>

 Ajouter la quantité de produits

			        <li role="presentation"<?php if($_GET['action']=='index') { echo' class="active"'; } ?>>Liste des quantités de produits

              <?php echo 'Restaurant sélectionné :    '; foreach ($select_resto_afficher as $key => $row) { echo ''.$row['lr_nom'].'
'; } ?>

                  	<?php if (!isset($_GET['ordre'])) {echo'Nom du produit';}
                                                      else if ($_GET['ordre'] == "nom_produit_asc") {echo'Nom du produit ';}
                                                      else if ($_GET['ordre'] == "nom_produit_desc") {echo'Nom du produit ';}
                                                      else if ($_GET['ordre'] == "nbr_produit_dispo_desc") {echo'Nom du produit';}
                                                      else if ($_GET['ordre'] == "nbr_produit_dispo_asc") {echo'Nom du produit';}?>

                    <?php if (!isset($_GET['ordre'])) {echo'Quantités de produits disponibles ';}
                                                      else if ($_GET['ordre'] == "nbr_produit_dispo_desc") {echo'Quantités de produits disponibles ';}
                                                      else if ($_GET['ordre'] == "nbr_produit_dispo_asc") {echo'Quantités de produits disponibles ';}
                                                      else if ($_GET['ordre'] == "nom_produit_asc") {echo'Quantités de produits disponibles';}
                                                      else if ($_GET['ordre'] == "nom_produit_desc") {echo'Quantités de produits disponibles';}?>
                    Ajoutés des quantités

                  <?php foreach ($afficher_quantites as $key => $row) {
                              echo'
';
                              echo"".$row['lp_nom']."	";
                              echo"".$row['lp_quantites']." quantités de produits	";
                              echo'Ajoutés des quantités	';
                              echo"
";
                        }
                  ?>

<?php include_once('../app/view/include/footer.inc.php'); ?>


text:
'use strict';

var
  bodyParser = require('body-parser'),
  express = require('express'),
  iCalendar = require('./lib/icalendar');

var event1 = {
  "@id": "http://calendar.bergnet.org/2014-09-03-11-00#event",
  "startDate": "2014-11-02T11:00:00+02:00",
  "endDate": "2014-11-02T12:00:00+02:00",
  "description": "Test",
  "location": "Landshut"
};

var event2 = {
  "@id": "http://calendar.bergnet.org/2014-09-05-21-00#event",
  "startDate": "2014-11-01T21:00:00Z",
  "endDate": "2014-11-01T23:00:00Z",
  "description": "Test",
  "location": "Weng",
  "attendee": [
    {"@id": "https://www.bergnet.org/people/bergi/card#me"},
    {"@id": "https://www.bergnet.org/people/bergi/card#otherme"} ]
};

var
  app = express(),
  calendar = new iCalendar.ICalendar();

calendar.on('event:added', function (event) {
  console.log('event:added');
  console.log(event.toJSON());
});

calendar.on('event:updated', function (event) {
  console.log('event:updated');
  console.log(event.toJSON());
});

calendar.on('event:removed', function (event) {
  console.log('event:removed');
  console.log(event.toJSON());
});

app.use(require('morgan')('dev'));
app.use(bodyParser.raw({type: 'text/calendar'}));
app.use('/calendar', calendar.middleware);

calendar.addEvent(event1);
calendar.addEvent(event2);

var server = app.listen(3000, function() {
  console.log('Listening on port %d', server.address().port);
});


text:
<?php

/*
 * Entry point of TMLVW
 * List files in a Galeria-compatible way
 */

// config file you can edit
require_once 'src/config.php';

// other files
require_once 'src/generator.php';
require_once 'src/helper.php';

$allFiles = listFilesByDate($config['photos_path'], $allDates, $last);

// If URL is "lastest", redirect to last taken
if (isset($_GET['latest']) && $last) {
    header('Location: index.php?year='.$last->format('Y').'&month='.$last->format('m').'&date='.$last->format('d'));
}

$filtered = getFilesForParameters($allFiles, $_GET);
$resized = getResizedFiles($config, $filtered);

?>
<!doctype html>

        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="assets/galleria/themes/classic/galleria.classic.css">

        <link rel="stylesheet" type="text/css" href="assets/style.css" />

                <?php
                    $months = [];

                    foreach ($allDates as $aDatetime) { /** @var DateTime $aDatetime */
                        $year = $aDatetime->format('Y');
                        $month = $aDatetime->format('m');
                        $date = $aDatetime->format('d');
                        $hasPicture = isset($allFiles[$year]) && isset($allFiles[$year][$month]) && isset($allFiles[$year][$month][$date]);
                        $isCurrent = isset($_GET['year']) && $_GET['year'] == $year && isset($_GET['month']) && $_GET['month'] == $month && isset($_GET['date']) && $_GET['date'] == $date;
                        $link = $hasPicture ? '?year='.$year.'&month='.$month.'&date='.$date : '#';
                        $months[$month] = $month.'.'.$year;

                        echo '
'.$date.'
'.$aDatetime->format('M').'
';
                    }
                ?>

                    <select id="monthSelect">
                        <?php
                            foreach ($months as $month => $fullDate) {
                                echo '<option value="'.$month.'">'.$fullDate.'</option>';
                            }
                        ?>
                    </select>

            <?php foreach ($resized as $file) {
                    // We trust data as they are from filenames
                    echo '';

                    $currentMonth = $file['month'];
                }
            ?>