@Override
  public boolean onCommand(
      final CommandSender sender, Command command, String label, String[] args) {
    // /tempnotice <player> <duration> <notice>
    if (!sender.hasPermission("cloudbans.notice.tempnotice")) {
      sender.sendMessage(ChatColor.RED + "You don't have enough permissions for that.");
      return true;
    }

    if (args.length < 2) {
      sender.sendMessage(ChatColor.RED + "Your missing arguments for this command.");
      return false;
    }

    if (sender instanceof BlockCommandSender) {
      sender.sendMessage(
          ChatColor.RED
              + "For security reasons this command can only executed by a player or the console!");
      return true;
    }

    NoticeRequestBuilder builder = new NoticeRequestBuilder();
    builder.setServer(config.getServerUuid());

    if (args.length > 2) {
      String[] notice = Arrays.copyOfRange(args, 2, args.length);
      String finalNotice = Joiner.on(" ").join(notice);
      builder.setNotice(finalNotice);
    }

    if (sender instanceof Player) {
      builder.setIssuer(((Player) sender).getUniqueId());
    }

    final NoticeRequest request = builder.build();
    CommandUtils.parseTarget(request, args[0]);

    Future<NoticeResponse> future = client.createNotice(request);
    Futures.addCallback(
        JdkFutureAdapters.listenInPoolThread(future, executor),
        new FutureCallback<NoticeResponse>() {
          @Override
          public void onSuccess(NoticeResponse result) {
            switch (result.getNotice().getDelayState()) {
              case EXECUTED:
                sender.sendMessage(ChatColor.GREEN + "Notice executed");
                break;
              case QUEUED:
                sender.sendMessage(ChatColor.GREEN + "Notice will be executed soon.");
                break;
            }
          }

          @Override
          public void onFailure(Throwable t) {
            sender.sendMessage(ChatColor.RED + "Notice was not executed successfully.");
            LOGGER.log(Level.SEVERE, "An error occured while executing notice request.", t);
          }
        });
    return true;
  }
  private void sendGatewayArpRequest(
      final Node externalNetworkBridge,
      final Ipv4Address gatewayIp,
      final Ipv4Address sourceIpAddress,
      final MacAddress sourceMacAddress) {
    final ArpMessageAddress senderAddress =
        new ArpMessageAddress(sourceMacAddress, sourceIpAddress);

    // Build arp reply router flow
    final Flow arpReplyToControllerFlow = createArpReplyToControllerFlow(senderAddress, gatewayIp);

    final InstanceIdentifier<Node> nodeIid =
        InstanceIdentifier.builder(Nodes.class)
            .child(Node.class, externalNetworkBridge.getKey())
            .build();
    final InstanceIdentifier<Flow> flowIid = createFlowIid(arpReplyToControllerFlow, nodeIid);
    final NodeRef nodeRef = new NodeRef(nodeIid);

    // Install flow
    Future<RpcResult<AddFlowOutput>> addFlowResult =
        flowService.addFlow(
            new AddFlowInputBuilder(arpReplyToControllerFlow)
                .setFlowRef(new FlowRef(flowIid))
                .setNode(nodeRef)
                .build());
    // wait for flow installation
    Futures.addCallback(
        JdkFutureAdapters.listenInPoolThread(addFlowResult),
        new FutureCallback<RpcResult<AddFlowOutput>>() {

          @Override
          public void onSuccess(RpcResult<AddFlowOutput> result) {
            if (!result.isSuccessful()) {
              LOG.warn(
                  "Flow to route ARP Reply to Controller is not installed successfully : {} \nErrors: {}",
                  flowIid,
                  result.getErrors());
              return;
            }
            LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);

            ArpResolverMetadata gatewayArpMetadata = gatewayToArpMetadataMap.get(gatewayIp);
            if (gatewayArpMetadata == null) {
              LOG.warn("No metadata found for gatewayIp: {}", gatewayIp);
              return;
            }

            // cache metadata
            gatewayArpMetadata.setFlowToRemove(
                new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());

            // get MAC DA for ARP packets
            MacAddress arpRequestDestMacAddress = gatewayArpMetadata.getArpRequestDestMacAddress();

            // Send ARP request packets
            for (NodeConnector egressNc : externalNetworkBridge.getNodeConnector()) {
              KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> egressNcIid =
                  nodeIid.child(NodeConnector.class, new NodeConnectorKey(egressNc.getId()));
              ListenableFuture<RpcResult<Void>> futureSendArpResult =
                  arpSender.sendArp(
                      senderAddress, gatewayIp, arpRequestDestMacAddress, egressNcIid);
              Futures.addCallback(futureSendArpResult, logResult(gatewayIp, egressNcIid));
            }
          }

          @Override
          public void onFailure(Throwable t) {
            LOG.warn("ARP Reply to Controller flow was not created: {}", flowIid, t);
          }
        });
  }