/** On Notice */
  @Override
  protected void onNotice(
      String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) {
    // Post notice to currently selected conversation
    Conversation conversation;

    if (service.getSettings().showNoticeInServerWindow()) {
      conversation = server.getConversation(ServerInfo.DEFAULT_NAME);
    } else {
      conversation = server.getConversation(server.getSelectedConversation());

      if (conversation == null) {
        // Fallback: Use ServerInfo view
        conversation = server.getConversation(ServerInfo.DEFAULT_NAME);
      }
    }

    Message message = new Message("-" + sourceNick + "- " + notice);
    message.setIcon(R.drawable.info);
    conversation.addMessage(message);

    Intent intent =
        Broadcast.createConversationIntent(
            Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName());
    service.sendBroadcast(intent);
  }
  /** On Join */
  @Override
  protected void onJoin(String target, String sender, String login, String hostname) {
    if (sender.equalsIgnoreCase(getNick()) && server.getConversation(target) == null) {
      // We joined a new channel
      Conversation conversation = new Channel(target);
      conversation.setHistorySize(service.getSettings().getHistorySize());
      server.addConversation(conversation);

      Intent intent =
          Broadcast.createConversationIntent(Broadcast.CONVERSATION_NEW, server.getId(), target);
      service.sendBroadcast(intent);
    } else if (service.getSettings().showJoinPartAndQuit()) {
      Message message =
          new Message(service.getString(R.string.message_join, sender), Message.TYPE_MISC);

      message.setIcon(R.drawable.join);
      message.setColor(Message.COLOR_GREEN);
      server.getConversation(target).addMessage(message);

      Intent intent =
          Broadcast.createConversationIntent(
              Broadcast.CONVERSATION_MESSAGE, server.getId(), target);
      service.sendBroadcast(intent);
    }
  }
  /** On channel action */
  @Override
  protected void onAction(
      String sender, String login, String hostname, String target, String action) {
    Conversation conversation;

    Message message = new Message(sender + " " + action);
    message.setIcon(R.drawable.action);

    String queryNick = target;
    if (queryNick.equals(this.getNick())) {
      // We are the target - this is an action in a query
      queryNick = sender;
    }
    conversation = server.getConversation(queryNick);

    if (conversation == null) {
      // Open a query if there's none yet
      conversation = new Query(queryNick);
      conversation.setHistorySize(service.getSettings().getHistorySize());
      server.addConversation(conversation);
      conversation.addMessage(message);

      Intent intent =
          Broadcast.createConversationIntent(Broadcast.CONVERSATION_NEW, server.getId(), queryNick);
      service.sendBroadcast(intent);
    } else {
      conversation.addMessage(message);

      Intent intent =
          Broadcast.createConversationIntent(
              Broadcast.CONVERSATION_MESSAGE, server.getId(), queryNick);
      service.sendBroadcast(intent);
    }

    if (sender.equals(this.getNick())) {
      // Don't notify for something sent in our name
      return;
    }

    boolean mentioned = isMentioned(action);
    if (mentioned || target.equals(this.getNick())) {
      if (conversation.getStatus() != Conversation.STATUS_SELECTED || !server.getIsForeground()) {
        service.addNewMention(
            server.getId(),
            conversation,
            conversation.getName() + ": " + sender + " " + action,
            service.getSettings().isVibrateHighlightEnabled(),
            service.getSettings().isSoundHighlightEnabled());
      }
    }

    if (mentioned) {
      // highlight
      message.setColor(Message.COLOR_RED);
      conversation.setStatus(Conversation.STATUS_HIGHLIGHT);
    }
  }
  /** On Quit */
  @Override
  protected void onQuit(
      String sourceNick, String sourceLogin, String sourceHostname, String reason) {
    if (sourceNick.equals(this.getNick())) {
      return;
    }

    if (service.getSettings().showJoinPartAndQuit()) {
      Vector<String> channels = getChannelsByNickname(sourceNick);

      for (String target : channels) {
        Message message =
            new Message(
                service.getString(R.string.message_quit, sourceNick, reason), Message.TYPE_MISC);

        message.setColor(Message.COLOR_GREEN);
        message.setIcon(R.drawable.quit);
        server.getConversation(target).addMessage(message);

        Intent intent =
            Broadcast.createConversationIntent(
                Broadcast.CONVERSATION_MESSAGE, server.getId(), target);
        service.sendBroadcast(intent);
      }

      // Look if there's a query to update
      Conversation conversation = server.getConversation(sourceNick);

      if (conversation != null) {
        Message message =
            new Message(
                service.getString(R.string.message_quit, sourceNick, reason), Message.TYPE_MISC);

        message.setColor(Message.COLOR_GREEN);
        message.setIcon(R.drawable.quit);
        conversation.addMessage(message);

        Intent intent =
            Broadcast.createConversationIntent(
                Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName());
        service.sendBroadcast(intent);
      }
    }
  }
  /** On unknown */
  @Override
  protected void onUnknown(String line) {
    Message message = new Message(line);
    message.setIcon(R.drawable.action);
    message.setColor(Message.COLOR_GREY);
    server.getConversation(ServerInfo.DEFAULT_NAME).addMessage(message);

    Intent intent =
        Broadcast.createConversationIntent(
            Broadcast.CONVERSATION_MESSAGE, server.getId(), ServerInfo.DEFAULT_NAME);
    service.sendBroadcast(intent);
  }
  /** On Voice */
  @Override
  protected void onVoice(
      String target,
      String sourceNick,
      String sourceLogin,
      String sourceHostname,
      String recipient) {
    Message message = new Message(service.getString(R.string.message_voice, sourceNick, recipient));
    message.setIcon(R.drawable.voice);
    message.setColor(Message.COLOR_BLUE);
    server.getConversation(target).addMessage(message);

    Intent intent =
        Broadcast.createConversationIntent(Broadcast.CONVERSATION_MESSAGE, server.getId(), target);
    service.sendBroadcast(intent);
  }
  /** On disconnect */
  @Override
  public void onDisconnect() {
    // Call parent method to ensure "register" status is tracked
    super.onDisconnect();

    if (service.getSettings().isReconnectEnabled() && server.getStatus() != Status.DISCONNECTED) {
      setAutojoinChannels(server.getCurrentChannelNames());

      server.setStatus(Status.CONNECTING);
      service.connect(server);
    } else {
      server.setStatus(Status.DISCONNECTED);
    }

    service.notifyDisconnected(server.getTitle());

    Intent sIntent = Broadcast.createServerIntent(Broadcast.SERVER_UPDATE, server.getId());
    service.sendBroadcast(sIntent);

    Collection<Conversation> conversations = server.getConversations();

    for (Conversation conversation : conversations) {
      Message message = new Message(service.getString(R.string.message_disconnected));
      message.setIcon(R.drawable.error);
      message.setColor(Message.COLOR_RED);
      server.getConversation(conversation.getName()).addMessage(message);

      Intent cIntent =
          Broadcast.createConversationIntent(
              Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName());
      service.sendBroadcast(cIntent);
    }

    synchronized (isQuittingLock) {
      isQuitting = false;
      if (disposeRequested) {
        super.dispose();
      }
    }
  }
  /** On Part */
  @Override
  protected void onPart(String target, String sender, String login, String hostname) {
    if (sender.equals(getNick())) {
      // We parted a channel
      service.ackNewMentions(server.getId(), target);
      server.removeConversation(target);

      Intent intent =
          Broadcast.createConversationIntent(Broadcast.CONVERSATION_REMOVE, server.getId(), target);
      service.sendBroadcast(intent);
    } else if (service.getSettings().showJoinPartAndQuit()) {
      Message message =
          new Message(service.getString(R.string.message_part, sender), Message.TYPE_MISC);

      message.setColor(Message.COLOR_GREEN);
      message.setIcon(R.drawable.part);
      server.getConversation(target).addMessage(message);

      Intent intent =
          Broadcast.createConversationIntent(
              Broadcast.CONVERSATION_MESSAGE, server.getId(), target);
      service.sendBroadcast(intent);
    }
  }