/** {@inheritDoc} */
 @Override
 public void channelIteractableLaunched(ChannelInteractable agent) {
   if (agent.getSupportedChannels().contains(EcoChannel.class)) {
     CubeEcoChannel channel = agent.getChannel(CubeEcoChannel.class);
     if (channel != null) {
       this.channels.add(channel);
       channel.addEcoChannelListener(this);
     }
   }
 }
 /** {@inheritDoc} */
 @Override
 public void channelIteractableKilled(ChannelInteractable agent) {
   if (agent.getSupportedChannels().contains(CubeEcoChannel.class)) {
     CubeEcoChannel channel = agent.getChannel(CubeEcoChannel.class);
     if (channel != null) {
       channel.removeEcoChannelListener(this);
       this.channels.remove(channel);
     }
   }
 }
  /** {@inheritDoc} */
  @Override
  public void channelContentChanged() {
    synchronized (getTreeLock()) {
      State state = new State();
      EcoIdentity entity;
      EcoIdentity previousEcoEntity;

      for (CubeEcoChannel channel : this.channels) {
        if (channel.getAgentType() == AgentType.CUBE) {
          entity = channel.getEcoEntity();
          assert (entity != null);
          state.ecoStates.put(entity, channel.getEcoState());
          for (EcoRelation relation : channel.getAcquaintances()) {
            if (relation instanceof DownwardRelation) {
              DownwardRelation dr = (DownwardRelation) relation;
              if (dr.getMaster().equals(entity)) {
                if (this.planeEntity.equals(dr.getSlave())) {
                  // on ground
                  if (!state.onGround.add(entity)) {
                    state.isInconsistent = true;
                  }
                } else {
                  // on other
                  previousEcoEntity = state.map.put(dr.getSlave(), entity);
                  if (previousEcoEntity != null && !entity.equals(previousEcoEntity)) {
                    state.isInconsistent = true;
                  }
                }
              }
            }
          }
          state.isInitialization =
              state.isInitialization || channel.getEcoState().isInitializationState();
        }
      }

      if (!state.onGround.isEmpty()) {
        State lastState = getLastState();
        if (lastState == null || !lastState.equals(state)) {
          this.worldStates.add(state);
          int oldIndex = this.currentStateIndex;
          if (this.currentStateIndex < 0) {
            this.currentStateIndex = 0;
          } else if (this.currentStateIndex >= this.worldStates.size()) {
            this.currentStateIndex = this.worldStates.size() - 1;
          }
          updateUIComponents();
          if (this.currentStateIndex != oldIndex) repaint();
        }
      }
    }
  }