diff --git a/src/main/java/com/intel/jndn/utils/Server.java b/src/main/java/com/intel/jndn/utils/Server.java
deleted file mode 100644
index a5574a1..0000000
--- a/src/main/java/com/intel/jndn/utils/Server.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils;
-
-import com.intel.jndn.utils.event.NDNEvent;
-import com.intel.jndn.utils.event.NDNObservable;
-import com.intel.jndn.utils.event.NDNObserver;
-import java.io.IOException;
-import java.util.logging.Level;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Face;
-import net.named_data.jndn.ForwardingFlags;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import net.named_data.jndn.OnInterest;
-import net.named_data.jndn.OnRegisterFailed;
-import net.named_data.jndn.encoding.EncodingException;
-import net.named_data.jndn.security.KeyChain;
-import net.named_data.jndn.transport.Transport;
-import java.util.logging.Logger;
-
-/**
- * Provide a server to simplify serving data over the NDN network. Exposes two
- * main methods: put() for serving static, known data packets and on() for
- * serving dynamically created packets on-demand.
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class Server {
-
-  public static final long DEFAULT_SLEEP_TIME = 20;
-  public static final long DEFAULT_TIMEOUT = 2000;
-  private static final Logger logger = Logger.getLogger(Server.class.getName());
-  private static Server defaultInstance;
-  private KeyChain keyChain;
-  private Name certificateName;
-
-  /**
-   * Singleton access for simpler server use
-   *
-   * @return
-   */
-  public static Server getDefault() {
-    if (defaultInstance == null) {
-      defaultInstance = new Server();
-    }
-    return defaultInstance;
-  }
-
-  /**
-   * Constructor
-   */
-  public Server() {
-    // no signing
-  }
-
-  /**
-   * Constructor; enables signing
-   *
-   * @param keyChain
-   * @param certificateName
-   */
-  public Server(KeyChain keyChain, Name certificateName) {
-    this.keyChain = keyChain;
-    this.certificateName = certificateName;
-  }
-
-  /**
-   * Synchronously serve a Data on the given face until one request accesses the
-   * data; will return incoming Interest request.
-   * <pre><code> Interest request = Client.putSync(face, data); </code></pre>
-   *
-   * @param face
-   * @param data
-   * @return
-   */
-  public Interest putSync(Face face, final Data data) {
-    // setup event
-    long startTime = System.currentTimeMillis();
-    final String dataName = data.getName().toUri();
-    final NDNEvent event = new NDNEvent();
-
-    // setup flags
-    ForwardingFlags flags = new ForwardingFlags();
-    flags.setCapture(true);
-
-    // register the data name on the face
-    try {
-      face.registerPrefix(data.getName(), new OnInterest() {
-        @Override
-        public void onInterest(Name prefix, Interest interest, Transport transport, long registeredPrefixId) {
-          // sign packet
-          if (keyChain != null) {
-            try {
-              keyChain.sign(data, certificateName != null ? certificateName : keyChain.getDefaultCertificateName());
-            } catch (net.named_data.jndn.security.SecurityException e) {
-              logger.severe("Failed to sign data for: " + dataName + e);
-              event.fromPacket(e);
-            }
-          }
-
-          // send packet
-          try {
-            transport.send(data.wireEncode().buf());
-            logger.fine("Sent data: " + dataName);
-            event.fromPacket(interest);
-          } catch (IOException e) {
-            logger.severe("Failed to send data for: " + dataName);
-            event.fromPacket(e);
-          }
-        }
-      }, new OnRegisterFailed() {
-        @Override
-        public void onRegisterFailed(Name prefix) {
-          event.fromPacket(new Exception("Failed to register name: " + dataName));
-        }
-      }, flags);
-      logger.info("Registered data: " + dataName);
-    } catch (IOException e) {
-      logger.severe("Could not connect to face to register prefix: " + dataName + e);
-      event.fromPacket(e);
-    } catch (net.named_data.jndn.security.SecurityException e) {
-      logger.severe("Error registering prefix: " + dataName + e);
-      event.fromPacket(e);
-    }
-
-    // process eventCount until one response is sent or error
-    while (event.getPacket() == null) {
-      try {
-        synchronized (face) {
-          face.processEvents();
-        }
-      } catch (IOException | EncodingException e) {
-        logger.log(Level.WARNING, "Failed to process events.", e);
-        event.fromPacket(e);
-      }
-      sleep();
-    }
-
-    // return
-    logger.fine("Request time (ms): " + (event.getTimestamp() - startTime));
-    return (event.isSuccess()) ? (Interest) event.getPacket() : null;
-  }
-
-  /**
-   * Asynchronously serve a Data on the given face until an observer stops it.
-   * E.g.: NDNObserver observer = Client.put(face, data); // when finished
-   * serving the data, stop the background thread observer.stop();
-   *
-   * @param face
-   * @param data
-   * @return
-   */
-  public NDNObserver put(final Face face, final Data data) {
-    // setup observer
-    final NDNObserver observer = new NDNObserver();
-    final NDNObservable eventHandler = new NDNObservable();
-    eventHandler.addObserver(observer);
-
-    // setup interest handler
-    final OnInterest interestHandler = new OnInterest() {
-      @Override
-      public void onInterest(Name prefix, Interest interest, Transport transport, long registeredPrefixId) {
-        // sign packet
-        if (keyChain != null) {
-          try {
-            keyChain.sign(data, certificateName != null ? certificateName : keyChain.getDefaultCertificateName());
-          } catch (net.named_data.jndn.security.SecurityException e) {
-            logger.severe("Failed to sign data for: " + data.getName().toUri() + e);
-            eventHandler.notify(e);
-          }
-        }
-
-        // send packet
-        try {
-          transport.send(data.wireEncode().buf());
-        } catch (IOException e) {
-          logger.severe("Failed to send data for: " + data.getName().toUri());
-          eventHandler.notify(e);
-        }
-      }
-    };
-
-    // setup failure handler
-    final OnRegisterFailed failureHandler = new OnRegisterFailed() {
-      @Override
-      public void onRegisterFailed(Name prefix) {
-        logger.severe("Failed to register name to put: " + data.getName().toUri());
-        eventHandler.notify(new Exception("Failed to register name to put: " + data.getName().toUri()));
-      }
-    };
-
-    // setup forwarding flags
-    final ForwardingFlags flags = new ForwardingFlags();
-    flags.setCapture(true); // no shorter routes will answer for this prefix, see http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#Route-inheritance
-    flags.setChildInherit(false); // the interest name must be exact, no child components after the prefix
-
-    // start background thread
-    Thread backgroundThread = new Thread(new Runnable() {
-      @Override
-      public void run() {
-        // register name on the face
-        try {
-          face.registerPrefix(data.getName(), interestHandler, failureHandler, flags);
-          logger.info("Registered data : " + data.getName().toUri());
-        } catch (IOException e) {
-          logger.severe("Could not connect to face to register prefix: " + data.getName().toUri() + e);
-          eventHandler.notify(e);
-        } catch (net.named_data.jndn.security.SecurityException e) {
-          logger.severe("Error registering prefix: " + data.getName().toUri() + e);
-          eventHandler.notify(e);
-        }
-
-        // process eventCount until a request is received
-        while (observer.interestCount() == 0 && observer.errorCount() == 0 && !observer.mustStop()) {
-          try {
-            synchronized (face) {
-              face.processEvents();
-            }
-          } catch (IOException | EncodingException e) {
-            logger.log(Level.WARNING, "Failed to process events.", e);
-            eventHandler.notify(e);
-          }
-          sleep();
-        }
-      }
-    });
-    backgroundThread.setName(String.format("Server.put(%s)", data.getName().toUri()));
-    backgroundThread.setDaemon(true);
-    backgroundThread.start();
-
-    return observer;
-  }
-
-  /**
-   * Register a prefix on the face to serve Data packets for incoming Interests.
-   * This method will create a background thread to process events until the
-   * user calls stop() on the returned observer
-   *
-   * @param face
-   * @param prefix
-   * @param handler
-   * @return
-   */
-  public NDNObserver on(final Face face, final Name prefix, final OnServeInterest handler) {
-    // setup observer
-    final NDNObserver observer = new NDNObserver();
-    final NDNObservable eventHandler = new NDNObservable();
-    eventHandler.addObserver(observer);
-
-    // setup interest handler
-    final OnInterest interestHandler = new OnInterest() {
-      @Override
-      public void onInterest(Name prefix, Interest interest, Transport transport, long registeredPrefixId) {
-        // notify observers of interest received
-        eventHandler.notify(interest);
-
-        // grab data from OnServeInterest handler
-        Data data = handler.onInterest(prefix, interest);
-
-        // sign packet
-        if (keyChain != null) {
-          try {
-            keyChain.sign(data, certificateName != null ? certificateName : keyChain.getDefaultCertificateName());
-          } catch (net.named_data.jndn.security.SecurityException e) {
-            logger.severe("Failed to sign data for: " + interest.getName().toUri() + e);
-            eventHandler.notify(e);
-          }
-        }
-
-        // send packet
-        try {
-          transport.send(data.wireEncode().buf());
-          eventHandler.notify(data); // notify observers of data sent
-        } catch (IOException e) {
-          logger.severe("Failed to send data for: " + interest.getName().toUri());
-          eventHandler.notify(e);
-        }
-      }
-    };
-
-    // setup failure handler
-    final OnRegisterFailed failureHandler = new OnRegisterFailed() {
-      @Override
-      public void onRegisterFailed(Name prefix) {
-        logger.severe("Failed to register name to put: " + prefix.toUri());
-        eventHandler.notify(new Exception("Failed to register name to put: " + prefix.toUri()));
-      }
-    };
-
-    // setup forwarding flags
-    final ForwardingFlags flags = new ForwardingFlags();
-    flags.setCapture(true); // no shorter routes will answer for this prefix, see http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#Route-inheritance
-    flags.setChildInherit(true); // the interest name may have child components after the prefix
-
-    // start background thread
-    Thread backgroundThread = new Thread(new Runnable() {
-      @Override
-      public void run() {
-        // register name on the face
-        try {
-          face.registerPrefix(prefix, interestHandler, failureHandler, flags);
-          logger.info("Registered data : " + prefix.toUri());
-        } catch (IOException e) {
-          logger.severe("Could not connect to face to register prefix: " + prefix.toUri() + e);
-          eventHandler.notify(e);
-        } catch (net.named_data.jndn.security.SecurityException e) {
-          logger.severe("Error registering prefix: " + prefix.toUri() + e);
-          eventHandler.notify(e);
-        }
-
-        // process events until told to stop or error bubbles up
-        while (observer.errorCount() == 0 && !observer.mustStop()) {
-          try {
-            synchronized (face) {
-              face.processEvents();
-            }
-          } catch (IOException | EncodingException e) {
-            logger.log(Level.WARNING, "Failed to process events.", e);
-            eventHandler.notify(e);
-          }
-          sleep();
-        }
-      }
-    });
-    backgroundThread.setName(String.format("Server.on(%s)", prefix.toUri()));
-    backgroundThread.setDaemon(true);
-    backgroundThread.start();
-
-    return observer;
-  }
-
-  /**
-   * Put the current thread to sleep to allow time for IO
-   */
-  protected void sleep() {
-    try {
-      Thread.currentThread().sleep(DEFAULT_SLEEP_TIME);
-    } catch (InterruptedException e) {
-      logger.severe("Event loop interrupted." + e);
-    }
-  }
-
-}
diff --git a/src/main/java/com/intel/jndn/utils/event/NDNEvent.java b/src/main/java/com/intel/jndn/utils/event/NDNEvent.java
deleted file mode 100644
index 43f8e7e..0000000
--- a/src/main/java/com/intel/jndn/utils/event/NDNEvent.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils.event;
-
-/**
- * Signals an event (from Client or Server) for observers to act on
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class NDNEvent<T> {
-
-  protected boolean success;
-  protected long timestamp;
-  protected T packet;
-
-  /**
-   * Constructor
-   */
-  public NDNEvent() {
-    timestamp = System.currentTimeMillis();
-    success = false; // an event without a packet is a failed event
-  }
-
-  /**
-   * Constructor
-   *
-   * @param packet
-   */
-  public NDNEvent(T packet) {
-    fromPacket(packet);
-  }
-
-  /**
-   * Build this event from a passed packet; the event is considered a failure if
-   * the packet is any type of Exception
-   *
-   * @param packet
-   */
-  public final void fromPacket(T packet) {
-    this.timestamp = System.currentTimeMillis();
-    this.success = !Exception.class.isInstance(packet);
-    this.packet = packet;
-  }
-
-  /**
-   * Retrieve success status
-   *
-   * @return
-   */
-  public boolean isSuccess() {
-    return success;
-  }
-
-  /**
-   * Retrieve event timestamp
-   *
-   * @return
-   */
-  public long getTimestamp() {
-    return timestamp;
-  }
-
-  /**
-   * Retrieve event packet
-   *
-   * @return
-   */
-  public T getPacket() {
-    return packet;
-  }
-}
diff --git a/src/main/java/com/intel/jndn/utils/event/NDNObservable.java b/src/main/java/com/intel/jndn/utils/event/NDNObservable.java
deleted file mode 100644
index df64df6..0000000
--- a/src/main/java/com/intel/jndn/utils/event/NDNObservable.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils.event;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Observable;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import net.named_data.jndn.OnData;
-import net.named_data.jndn.OnInterest;
-import net.named_data.jndn.OnTimeout;
-import net.named_data.jndn.transport.Transport;
-
-/**
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class NDNObservable extends Observable implements OnData, OnTimeout, OnInterest {
-
-  protected List<NDNEvent> events = new ArrayList<>();
-  protected List<Interest> incomingInterestPackets = new ArrayList<>();
-  protected List<Data> incomingDataPackets;
-
-  /**
-   * Generic notification
-   *
-   * @param <T>
-   * @param packet
-   */
-  public <T> void notify(T packet) {
-    setChanged();
-    notifyObservers(new NDNEvent(packet));
-  }
-
-  /**
-   * Handle data packets
-   *
-   * @param interest
-   * @param data
-   */
-  @Override
-  public void onData(Interest interest, Data data) {
-    notify(data);
-  }
-
-  /**
-   * Handle exceptions
-   *
-   * @param e
-   */
-  public void onError(Exception e) {
-    notify(e);
-  }
-
-  /**
-   * Handle timeouts
-   *
-   * @param interest
-   */
-  @Override
-  public void onTimeout(Interest interest) {
-    notify(new Exception("Interest timed out: " + interest.getName().toUri()));
-  }
-
-  /**
-   * Handle incoming interests
-   *
-   * @param prefix
-   * @param interest
-   * @param transport
-   * @param registeredPrefixId
-   */
-  @Override
-  public void onInterest(Name prefix, Interest interest, Transport transport, long registeredPrefixId) {
-    notify(interest); // TODO wrap
-  }
-
-  /**
-   * Helper to reference both outgoing interest and incoming data packets
-   */
-  class InterestDataPacket {
-
-    private Interest interest;
-    private Data data;
-
-    public InterestDataPacket(Interest interest, Data data) {
-      this.interest = interest;
-      this.data = data;
-    }
-
-    public Data getData() {
-      return data;
-    }
-
-    public Interest getInterest() {
-      return interest;
-    }
-  }
-
-  /**
-   * Helper to reference both incoming interest and the transport to send data
-   * on
-   */
-  class InterestTransportPacket {
-
-    private Interest interest;
-    private Transport transport;
-
-    public InterestTransportPacket(Interest interest, Transport transport) {
-      this.interest = interest;
-      this.transport = transport;
-    }
-
-    public Interest getInterest() {
-      return interest;
-    }
-
-    public Transport getTransport() {
-      return transport;
-    }
-
-  }
-}
diff --git a/src/main/java/com/intel/jndn/utils/event/NDNObserver.java b/src/main/java/com/intel/jndn/utils/event/NDNObserver.java
deleted file mode 100644
index 5ad3d8e..0000000
--- a/src/main/java/com/intel/jndn/utils/event/NDNObserver.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils.event;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Observable;
-import java.util.Observer;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-
-/**
- * Track asynchronous events from Client and Server
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class NDNObserver implements Observer {
-
-  protected List<NDNEvent> events = new ArrayList<>();
-  protected long timestamp;
-  protected OnEvent then;
-  protected boolean stopThread;
-
-  /**
-   * Constructor
-   */
-  public NDNObserver() {
-    timestamp = System.currentTimeMillis();
-  }
-
-  /**
-   * Receive notifications from observables
-   *
-   * @param o
-   * @param arg
-   */
-  @Override
-  public void update(Observable o, Object arg) {
-    NDNEvent event = (NDNEvent) arg;
-    events.add(event);
-    // call onData callbacks
-    if (then != null) {
-      then.onEvent(event);
-    }
-  }
-
-  /**
-   * Register a handler for events
-   *
-   * @param callback
-   * @return
-   */
-  public NDNObserver then(OnEvent callback) {
-    then = callback;
-    return this;
-  }
-
-  /**
-   * Count the number of eventCount observed
-   *
-   * @return
-   */
-  public int eventCount() {
-    return events.size();
-  }
-
-  /**
-   * Count the number of interest packets observed (received or sent)
-   *
-   * @return
-   */
-  public int interestCount() {
-    return count(Interest.class);
-  }
-
-  /**
-   * Count the number of Data packets observed
-   *
-   * @return
-   */
-  public int dataCount() {
-    return count(Data.class);
-  }
-
-  /**
-   * Count the number of errors observed
-   *
-   * @return
-   */
-  public int errorCount() {
-    return count(Exception.class);
-  }
-
-  /**
-   * Count the number of observed packets by type
-   *
-   * @param type
-   * @return
-   */
-  public int count(Class type) {
-    int count = 0;
-    for (NDNEvent event : events) {
-      if (type.isInstance(event.packet)) {
-        count++;
-      }
-    }
-    return count;
-  }
-
-  /**
-   * Calculate time elapsed since observer started observing until this method
-   * is called
-   *
-   * @return
-   */
-  public long getTimeSinceStart() {
-    if (getLast() != null) {
-      return getLast().getTimestamp() - timestamp;
-    }
-    return -1;
-  }
-
-  /**
-   * Retrieve a list of observed events
-   *
-   * @return event or null
-   */
-  public List<NDNEvent> getEvents() {
-    return events;
-  }
-
-  /**
-   * Retrieve the first event
-   *
-   * @return event or null
-   */
-  public NDNEvent getFirst() {
-    if (events.size() > 0) {
-      return events.get(0);
-    }
-    return null;
-  }
-
-  /**
-   * Retrieve the last event
-   *
-   * @return event or null
-   */
-  public NDNEvent getLast() {
-    if (events.size() > 0) {
-      return events.get(events.size() - 1);
-    }
-    return null;
-  }
-
-  /**
-   * Stop the current Client thread; used by asynchronous Client methods to stop
-   * the request/response thread
-   */
-  public void stop() {
-    stopThread = true;
-  }
-
-  /**
-   * Check the current stop status; used by asynchronous Client methods to stop
-   * the request/response thread
-   *
-   * @return
-   */
-  public boolean mustStop() {
-    return stopThread;
-  }
-}
diff --git a/src/main/java/com/intel/jndn/utils/event/OnEvent.java b/src/main/java/com/intel/jndn/utils/event/OnEvent.java
deleted file mode 100644
index 243521d..0000000
--- a/src/main/java/com/intel/jndn/utils/event/OnEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils.event;
-
-/**
- * Interface for registering generic event handlers. E.g.: observer.then((event)
- * => doSomething(event.getFirst()));
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public interface OnEvent {
-
-  public void onEvent(NDNEvent event);
-}
diff --git a/src/test/java/com/intel/jndn/utils/ServerTest.java b/src/test/java/com/intel/jndn/utils/ServerTest.java
deleted file mode 100644
index 0c2645b..0000000
--- a/src/test/java/com/intel/jndn/utils/ServerTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * jndn-utils
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.utils;
-
-import com.intel.jndn.utils.event.NDNObserver;
-import com.intel.jndn.mock.MockTransport;
-import java.util.logging.Logger;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Face;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import net.named_data.jndn.util.Blob;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- * Test Server.java
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class ServerTest {
-
-  /**
-   * Setup logging
-   */
-  private static final Logger logger = Logger.getLogger(SimpleClient.class.getName());
-
-  /**
-   * Test on functionality
-   * TODO more comprehensive tests with InternalFace
-   * @throws java.lang.InterruptedException
-   */
-  @Test
-  public void testOn() throws InterruptedException {
-    // setup face
-    MockTransport transport = new MockTransport();
-    Face face = new Face(transport, null);
-
-    // setup server
-    NDNObserver observer = Server.getDefault().on(face, new Name("/test/server/on"), new OnServeInterest() {
-      @Override
-      public Data onInterest(Name prefix, Interest interest) {
-        Data data = new Data(interest.getName());
-        data.setContent(new Blob("..."));
-        return data;
-      }
-    });
-    
-    // wait for background threads to run
-    Thread.sleep(100);
-
-    // check
-    assertEquals(1, transport.getSentInterestPackets().size());
-  }
-}
