/// <summary>
        /// Called by MultiClusterOracle when there is a configuration change.
        /// </summary>
        /// <returns></returns>
        public async Task OnMultiClusterConfigurationChange(MultiCluster.MultiClusterConfiguration newConfig)
        {
            Debug.Assert(newConfig != null);

            var oldConfig = Configuration;

            // process only if newer than what we already have
            if (!MultiClusterConfiguration.OlderThan(oldConfig, newConfig))
            {
                return;
            }

            Services.Log(LogLevel.Debug, "Processing Configuration {0}", newConfig);

            await this.OnConfigurationChange(newConfig); // updates Configuration and does any work required

            var added = oldConfig == null ? newConfig.Clusters : newConfig.Clusters.Except(oldConfig.Clusters);

            // if the multi-cluster is operated correctly, this grain should not be active before we are joined to the multicluster
            // but if we detect that anyway here, enforce a refresh to reduce risk of missed notifications
            if (!needInitialRead && added.Contains(Services.MyClusterId))
            {
                needRefresh = true;
                Services.Log(LogLevel.Debug, "Refresh Because of Join");
                worker.Notify();
            }

            if (notificationTracker != null)
            {
                var remoteInstances = Services.RegistrationStrategy.GetRemoteInstances(newConfig.Clusters, Services.MyClusterId).ToList();
                notificationTracker.UpdateNotificationTargets(remoteInstances);
            }
        }