@Override
  public BaseComponent apply(
      final com.gotofinal.messages.api.chat.component.BaseComponent baseComponent) {
    final BaseComponent cpy;
    if (baseComponent instanceof com.gotofinal.messages.api.chat.component.TextComponent) {
      cpy =
          new TextComponent(
              ((com.gotofinal.messages.api.chat.component.TextComponent) baseComponent).getText());
    } else if (baseComponent
        instanceof com.gotofinal.messages.api.chat.component.TranslatableComponent) {
      final com.gotofinal.messages.api.chat.component.TranslatableComponent tmp =
          (com.gotofinal.messages.api.chat.component.TranslatableComponent) baseComponent;
      cpy = new TranslatableComponent(tmp.getTranslate(), tmp.getWith());
    } else {
      throw new UnsupportedChatElement(baseComponent.toString());
    }
    cpy.setBold(baseComponent.isBoldRaw());
    cpy.setItalic(baseComponent.isItalicRaw());
    cpy.setObfuscated(baseComponent.isObfuscatedRaw());
    cpy.setStrikethrough(baseComponent.isStrikethroughRaw());
    cpy.setUnderlined(baseComponent.isUnderlinedRaw());
    cpy.setColor(this.getColor(baseComponent.getColorRaw()));

    {
      final com.gotofinal.messages.api.chat.component.ClickEvent tmp =
          baseComponent.getClickEvent();
      if (tmp != null) {
        final ClickEvent cpyEvt = new ClickEvent(this.getAction(tmp.getAction()), tmp.getValue());
        cpy.setClickEvent(cpyEvt);
      }
    }
    {
      final com.gotofinal.messages.api.chat.component.HoverEvent tmp =
          baseComponent.getHoverEvent();
      if (tmp != null) {
        final HoverEvent cpyEvt =
            new HoverEvent(this.getAction(tmp.getAction()), this.apply(tmp.getValue()));
        cpy.setHoverEvent(cpyEvt);
      }
    }

    final List<com.gotofinal.messages.api.chat.component.BaseComponent> extra =
        baseComponent.getExtra();
    if ((extra == null) || extra.isEmpty()) {
      return cpy;
    }
    for (final com.gotofinal.messages.api.chat.component.BaseComponent ext : extra) {
      cpy.addExtra(this.apply(ext));
    }
    return cpy;
  }