void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant)
        {
            // deduce and apply state changes involved
            var shellState = _stateManager.GetShellState();
            foreach (var feature in descriptor.Features) {
                var featureName = feature.Name;
                var featureState = shellState.Features.SingleOrDefault(f => f.Name == featureName);
                if (featureState == null) {
                    featureState = new ShellFeatureState {
                        Name = featureName
                    };
                    shellState.Features = shellState.Features.Concat(new[] { featureState });
                }
                if (!featureState.IsInstalled) {
                    _stateManager.UpdateInstalledState(featureState, ShellFeatureState.State.Rising);
                }
                if (!featureState.IsEnabled) {
                    _stateManager.UpdateEnabledState(featureState, ShellFeatureState.State.Rising);
                }
            }
            foreach (var featureState in shellState.Features) {
                var featureName = featureState.Name;
                if (descriptor.Features.Any(f => f.Name == featureName)) {
                    continue;
                }
                if (!featureState.IsDisabled) {
                    _stateManager.UpdateEnabledState(featureState, ShellFeatureState.State.Falling);
                }
            }

            FireApplyChangesIfNeeded();
        }
        public void UpdateInstalledState(ShellFeatureState featureState, ShellFeatureState.State value)
        {
            Logger.Debug("Feature {0} InstallState changed from {1} to {2}",
                         featureState.Name, featureState.InstallState, value);

            var featureStateRecord = FeatureRecord(featureState.Name);
            if (featureStateRecord.InstallState != featureState.InstallState) {
                Logger.Warning("Feature {0} prior InstallState was {1} when {2} was expected",
                               featureState.Name, featureStateRecord.InstallState, featureState.InstallState);
            }
            featureStateRecord.InstallState = value;
            featureState.InstallState = value;
        }
 static bool IsRising(ShellFeatureState state)
 {
     return state.InstallState == ShellFeatureState.State.Rising ||
            state.EnableState == ShellFeatureState.State.Rising;
 }
 private static bool FeatureShouldBeLoadedForStateChangeNotifications(ShellFeatureState shellFeatureState)
 {
     return FeatureIsChanging(shellFeatureState) || shellFeatureState.EnableState == ShellFeatureState.State.Up;
 }
 private static bool FeatureIsChanging(ShellFeatureState shellFeatureState)
 {
     if (shellFeatureState.EnableState == ShellFeatureState.State.Rising ||
         shellFeatureState.EnableState == ShellFeatureState.State.Falling) {
         return true;
     }
     if (shellFeatureState.InstallState == ShellFeatureState.State.Rising ||
         shellFeatureState.InstallState == ShellFeatureState.State.Falling) {
         return true;
     }
     return false;
 }