protected void RaiseComponentsChanged( ComponentModel componentModel, ChangeAction action )
 {
     var handler = ComponentsChanged;
      if ( handler != null )
      {
     handler( this, new ComponentsChangedEventArgs( componentModel, action ) );
      }
 }
 protected internal void TryDisconnect( ComponentModel component1, ComponentModel component2 )
 {
     component1.TryDisconnect( component2 );
 }
        private void CreateAndCombineComponents()
        {
            var newComponents = _componentFactory();

             // for each backend that must be started
             foreach ( var newComponent in newComponents )
             {
            try
            {
               newComponent.Disposed += Component_Disposed;

               // start it!
               _logger.Info( "Starting the new component '{0}'", newComponent.Name );
               newComponent.Start();

               var componentModel = new ComponentModel( newComponent );
               _startedComponents.Add( componentModel );
               RaiseComponentsChanged( componentModel, ChangeAction.Added );

               // connect new backend to relevant frontends
               foreach ( var connectableComponentModel in _startedComponents )
               {
                  try
                  {
                     TryConnect( connectableComponentModel, componentModel );
                  }
                  catch ( Exception e )
                  {
                     _logger.Log(
                        LogLevel.Error,
                        string.Format(
                           "Failed connecting the component '{0}' to the component '{1}'",
                           connectableComponentModel.Component.Name,
                           newComponent.Name ),
                        e );
                  }
               }
               _logger.Info( "Started the new component '{0}'", newComponent.Name );
            }
            catch ( Exception e )
            {
               _logger.Log(
                  LogLevel.Error,
                  string.Format(
                     "Failed starting new the component '{0}' due to: " + e.Message,
                     newComponent.Name ),
                  e );

               // make sure it is disposed
               newComponent.Dispose();
            }

            // all new backends are connected to existing frontends
             }
        }
        internal void Remove( ComponentModel component )
        {
            _connectedComponents.Remove( component );

             RaiseConnectedComponentsChanged( component, ChangeAction.Removed );
        }
        internal void Add( ComponentModel component )
        {
            _connectedComponents.Add( component );

             RaiseConnectedComponentsChanged( component, ChangeAction.Added );
        }
        internal void TryDisconnect( ComponentModel disconnectingComponent )
        {
            var disconnectingComponentInterface = disconnectingComponent.Component as IConnectableComponent;
             if ( disconnectingComponentInterface != null )
             {
            var disconnectingCommunicationInterface = disconnectingComponentInterface.GetCommunicationInterface();
            if ( disconnectingCommunicationInterface != null )
            {
               var canDisconnect = CanConnect( disconnectingCommunicationInterface );
               if ( canDisconnect )
               {
                  _logger.Info( "Disconnecting the component '{0}' to the component '{1}'", Component.Name, disconnectingComponentInterface.Name );

                  dynamic fe = Component;
                  dynamic bc = disconnectingCommunicationInterface;
                  fe.DisconnectComponent( bc ); // TODO: Change this to another method name

                  // update model
                  Remove( disconnectingComponent );
                  disconnectingComponent.Remove( this );

                  _logger.Info( "Disconnected the component '{0}' to the component '{1}'", Component.Name, disconnectingComponentInterface.Name );
               }
            }
             }
             else
             {
            // try to connect the other way, if the connecting component was not a connectable
            var thisComponent = Component as IConnectableComponent;
            if ( thisComponent != null )
            {
               var thisComponentCommunicationInterface = thisComponent.GetCommunicationInterface();
               if ( thisComponentCommunicationInterface != null )
               {
                  var canDisconnect = disconnectingComponent.CanConnect( thisComponentCommunicationInterface );
                  if ( canDisconnect )
                  {
                     _logger.Info( "Connecting the component '{0}' to the component '{1}'", disconnectingComponentInterface.Name, Component.Name );

                     dynamic fe = disconnectingComponent.Component;
                     dynamic bc = thisComponentCommunicationInterface;
                     fe.DisconnectComponent( bc ); // TODO: Change this to another method name

                     // update model
                     Remove( disconnectingComponent );
                     disconnectingComponent.Remove( this );

                     _logger.Info( "Connected the component '{0}' to the component '{1}'", disconnectingComponentInterface.Name, Component.Name );
                  }
               }
            }
             }
        }
        internal void TryConnect( ComponentModel connectingComponent )
        {
            var connectingComponentInterface = connectingComponent.Component as IConnectableComponent;
             if ( connectingComponentInterface != null )
             {
            var connectingCommunicationInterface = connectingComponentInterface.GetCommunicationInterface();
            if ( connectingCommunicationInterface != null )
            {
               var canConnect = CanConnect( connectingCommunicationInterface );
               if ( canConnect )
               {
                  _logger.Info( "Connecting the component '{0}' to the component '{1}'", Component.Name, connectingComponentInterface.Name );

                  dynamic fe = Component;
                  dynamic bc = connectingCommunicationInterface;
                  fe.ConnectComponent( bc );

                  // update model
                  Add( connectingComponent );
                  connectingComponent.Add( this );

                  _logger.Info( "Connected the component '{0}' to the component '{1}'", Component.Name, connectingComponentInterface.Name );
               }
            }
             }
             else
             {
            // try to connect the other way, if the connecting component was not a connectable
            var thisComponent = Component as IConnectableComponent;
            if ( thisComponent != null )
            {
               var thisComponentCommunicationInterface = thisComponent.GetCommunicationInterface();
               if ( thisComponentCommunicationInterface != null )
               {
                  var canConnect = connectingComponent.CanConnect( thisComponentCommunicationInterface );
                  if ( canConnect )
                  {
                     _logger.Info( "Connecting the component '{0}' to the component '{1}'", connectingComponent.Component.Name, Component.Name );

                     dynamic fe = connectingComponent.Component;
                     dynamic bc = thisComponentCommunicationInterface;
                     fe.ConnectComponent( bc );

                     // update model
                     Add( connectingComponent );
                     connectingComponent.Add( this );

                     _logger.Info( "Connected the component '{0}' to the component '{1}'", connectingComponent.Component.Name, Component.Name );
                  }
               }
            }
             }
        }