public synchronized void stopListener() {
    if (!listenerStarted) return;

    // shutdown listening for new switches
    try {
      listenerIOLoop.shutdown();
      listenSock.socket().close();
      listenSock.close();
    } catch (IOException e) {
      log.error("Failure shutting down listening socket", e);
    } finally {
      listenerStarted = false;
    }
  }
  public void shutDown() throws IOException {
    shuttingDown = true;
    livenessTimer.cancel();

    stopListener();

    // close the switch connections
    for (Iterator<Entry<Long, IOFSwitchExt>> it = activeSwitches.entrySet().iterator();
        it.hasNext(); ) {
      Entry<Long, IOFSwitchExt> entry = it.next();
      entry.getValue().getSocketChannel().socket().close();
      it.remove();
    }

    // shutdown the connected switch select loops
    for (IOLoop sl : switchIOLoops) {
      sl.shutdown();
    }

    es.shutdown();
    initializerExecutorService.shutdownNow();
    updatesThread.interrupt();
    log.info("Beacon Core Shutdown");
  }
  public synchronized void startListener() {
    if (listenerStarted) return;

    try {
      listenSock = ServerSocketChannel.open();
      listenSock.socket().setReceiveBufferSize(512 * 1024);
      listenSock.configureBlocking(false);
      if (listenAddress != null) {
        listenSock
            .socket()
            .bind(
                new java.net.InetSocketAddress(
                    InetAddress.getByAddress(IPv4.toIPv4AddressBytes(listenAddress)), listenPort));
      } else {
        listenSock.socket().bind(new java.net.InetSocketAddress(listenPort));
      }
      listenSock.socket().setReuseAddress(true);

      listenerIOLoop = new IOLoop(this, -1);
      // register this connection for accepting
      listenerIOLoop.register(listenSock, SelectionKey.OP_ACCEPT, listenSock);
    } catch (IOException e) {
      log.error("Failure opening listening socket", e);
      System.exit(-1);
    }

    log.info(
        "Controller listening on {}:{}", listenAddress == null ? "*" : listenAddress, listenPort);

    es.execute(
        new Runnable() {
          public void run() {
            // Start the listen loop
            try {
              listenerIOLoop.doLoop();
            } catch (Exception e) {
              log.error("Exception during accept loop, terminating thread", e);
            }
          }
        });

    listenerStarted = true;
  }
  protected void handleListenEvent(SelectionKey key, ServerSocketChannel ssc) throws IOException {
    SocketChannel sock = listenSock.accept();
    log.info("Switch connected from {}", sock.toString());
    sock.socket().setTcpNoDelay(this.noDelay);
    sock.configureBlocking(false);
    sock.socket().setSendBufferSize(1024 * 1024);
    OFSwitchImpl sw = new OFSwitchImpl();

    // Try to even the # of switches per thread
    // TODO something more intelligent here based on load
    IOLoop sl = null;
    for (IOLoop loop : switchIOLoops) {
      if (sl == null || loop.getStreams().size() < sl.getStreams().size()) sl = loop;
    }

    // register initially with no ops because we need the key to init the stream
    SelectionKey switchKey = sl.registerBlocking(sock, 0, sw);
    OFStream stream = new OFStream(sock, factory, switchKey, sl);
    stream.setImmediate(this.immediate);
    sw.setInputStream(stream);
    sw.setOutputStream(stream);
    sw.setSocketChannel(sock);
    sw.setBeaconProvider(this);
    sw.transitionToState(OFSwitchState.HELLO_SENT);

    addSwitch(sw);

    // Send HELLO
    stream.write(factory.getMessage(OFType.HELLO));

    // register for read
    switchKey.interestOps(SelectionKey.OP_READ);
    sl.addStream(stream);
    log.info("Added switch {} to IOLoop {}", sw, sl);
    sl.wakeup();
  }