diff --git a/src/main/java/com/intel/jndn/utils/repository/NavigableTreeRepository.java b/src/main/java/com/intel/jndn/utils/repository/NavigableTreeRepository.java
deleted file mode 100644
index ec47190..0000000
--- a/src/main/java/com/intel/jndn/utils/repository/NavigableTreeRepository.java
+++ /dev/null
@@ -1,146 +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.repository;
-
-import java.util.NavigableMap;
-import java.util.TreeMap;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-
-/**
- * Store {@link Data} packets in a {@link TreeMap}; this is an initial concept
- * class and should not be used in production. In tests, see
- * RepositoryTest.java, this class is faster on retrieval but not enough to make
- * up for its slow put().
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class NavigableTreeRepository implements Repository {
-
-  private NavigableMap<Name, PossibleData> storage = new TreeMap<>();
-
-  /**
-   * Helper data structure
-   */
-  private class PossibleData {
-
-    public PossibleData() {
-      // no data provided
-    }
-
-    public PossibleData(Data data) {
-      this.data = data;
-    }
-    public Data data;
-
-    public boolean hasData() {
-      return data != null;
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void put(Data data) {
-    storage.put(data.getName(), new PossibleData(data));
-
-    Name name = data.getName();
-    do {
-      name = name.getPrefix(-1);
-      if (storage.get(name) == null) {
-        storage.put(name, new PossibleData());
-      }
-    } while (name.size() > 0);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Data get(Interest interest) throws DataNotFoundException {
-    Data data;
-    if (interest.getChildSelector() == Interest.CHILD_SELECTOR_LEFT) {
-      data = getLowest(interest);
-    } else if (interest.getChildSelector() == Interest.CHILD_SELECTOR_RIGHT) {
-      data = getHighest(interest);
-    } else {
-      data = getFirstMatching(interest);
-    }
-    checkForNull(data);
-    return data;
-  }
-
-  /**
-   * @param interest the {@link Interest} to search with
-   * @return the lowest matching {@link Data} packet
-   */
-  private Data getLowest(Interest interest) {
-    PossibleData found = storage.get(interest.getName());
-
-    Name name = interest.getName();
-    while (found != null && interest.matchesName(name)) {
-      name = storage.lowerKey(name);
-      found = (name != null) ? storage.get(name) : null;
-    }
-
-    return found == null ? null : found.data;
-  }
-
-  /**
-   * @param interest the {@link Interest} to search with
-   * @return the highest matching {@link Data} packet
-   */
-  private Data getHighest(Interest interest) {
-    PossibleData found = storage.get(interest.getName());
-
-    if (found != null) {
-      Name name = interest.getName();
-      while (name != null && interest.matchesName(name)) {
-        found = storage.get(name);
-        name = storage.higherKey(name);
-      }
-    }
-
-    return found == null ? null : found.data;
-  }
-
-  /**
-   * @param interest the {@link Interest} to search with
-   * @return the first matching {@link Data} packet
-   */
-  private Data getFirstMatching(Interest interest) {
-    PossibleData found = storage.get(interest.getName());
-
-    Name name = interest.getName();
-    while (found != null && !found.hasData() && interest.matchesName(name)) {
-      name = storage.higherKey(name);
-      found = (name != null) ? storage.get(name) : null;
-    }
-
-    return found == null ? null : found.data;
-  }
-
-  /**
-   * @param data the {@link Data} packet to check
-   * @throws DataNotFoundException if data is null
-   */
-  private void checkForNull(Data data) throws DataNotFoundException {
-    if (data == null) {
-      throw new DataNotFoundException();
-    }
-  }
-
-}
diff --git a/src/test/java/com/intel/jndn/utils/repository/NavigableTreeRepositoryTest.java b/src/test/java/com/intel/jndn/utils/repository/NavigableTreeRepositoryTest.java
deleted file mode 100644
index e3add4d..0000000
--- a/src/test/java/com/intel/jndn/utils/repository/NavigableTreeRepositoryTest.java
+++ /dev/null
@@ -1,51 +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.repository;
-
-import com.intel.jndn.utils.repository.Repository;
-import com.intel.jndn.utils.repository.DataNotFoundException;
-import com.intel.jndn.utils.repository.NavigableTreeRepository;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import static org.junit.Assert.*;
-import org.junit.Test;
-
-/**
- * Test {@link NavigableTreeRepository}.
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class NavigableTreeRepositoryTest {
-
-  @Test
-  public void testNavigableTreeFunctionality() throws DataNotFoundException {
-    Repository repo = new NavigableTreeRepository();
-    repo.put(RepositoryTest.buildData("/a/b/c"));
-    Data data = repo.get(RepositoryTest.buildInterest("/a/b/c"));
-    assertEquals("...", data.getContent().toString());
-  }
-
-  @Test
-  public void testNavigableTreeChildSelectors() throws DataNotFoundException {
-    Repository repo = new NavigableTreeRepository();
-    RepositoryTest.assertChildSelectorsRetrieve(repo);
-  }
-  
-  @Test(expected = DataNotFoundException.class)
-  public void testFailure() throws DataNotFoundException{
-    Repository repo = new NavigableTreeRepository();
-    repo.get(new Interest(new Name("/unknown/data")));
-  }
-}
diff --git a/src/test/java/com/intel/jndn/utils/repository/RepositoryPerformanceTest.java b/src/test/java/com/intel/jndn/utils/repository/RepositoryPerformanceTest.java
deleted file mode 100644
index fa9ad07..0000000
--- a/src/test/java/com/intel/jndn/utils/repository/RepositoryPerformanceTest.java
+++ /dev/null
@@ -1,168 +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.repository;
-
-import static com.intel.jndn.utils.repository.RepoHelper.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.logging.Logger;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import static org.junit.Assert.*;
-import org.junit.Test;
-
-/**
- * Test NDN repositories, including performance
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class RepositoryPerformanceTest {
-
-  private static final Logger logger = Logger.getLogger(RepositoryPerformanceTest.class.getName());
-
-  @Test
-  public void testGenerator() {
-    List<Name> names = buildNames(100);
-    assertEquals(100, names.size());
-    assertNotSame(names.get(0), names.get(1));
-    assertNotSame(names.get(0), names.get(26));
-  }
-
-  /**
-   * Some conclusions: the tree is far, far slower to add but far, far faster on
-   * retrieval.
-   *
-   * @throws DataNotFoundException
-   */
-  @Test
-  public void testPerformance() throws DataNotFoundException {
-    double seconds = 1000000000.0;
-    List<Name> names = buildNames(1000);
-    List<Data> datas = buildDatas(names);
-    List<Interest> interests = buildInterests(names);
-
-    Repository repo1 = new ForLoopRepository();
-    long time1 = timeAddDatas(repo1, datas);
-    logger.info("Put in for-loop repo (sec): " + time1 / seconds);
-
-    Repository repo2 = new NavigableTreeRepository();
-    long time2 = timeAddDatas(repo2, datas);
-    logger.info("Put in tree repo (sec): " + time2 / seconds);
-
-    long time3 = timeFindDatas(repo1, interests);
-    logger.info("Get from for-loop repo (sec): " + time3 / seconds);
-
-    long time4 = timeFindDatas(repo2, interests);
-    logger.info("Get from tree repo (sec): " + time4 / seconds);
-
-    long time5 = timeFindChildSelectedDatas(repo1, interests);
-    logger.info("Get child-selected from for-loop repo (sec): " + time5 / seconds);
-
-    long time6 = timeFindChildSelectedDatas(repo2, interests);
-    logger.info("Get child-selected from tree repo (sec): " + time6 / seconds);
-  }
-
-  public static List<Name> buildNames(int size) {
-    List<Name> names = new ArrayList<>();
-    for (Name name : new NameGenerator(size)) {
-      names.add(name);
-    }
-    return names;
-  }
-
-  public static List<Data> buildDatas(List<Name> names) {
-    List<Data> datas = new ArrayList<>();
-    for (Name name : names) {
-      datas.add(buildData(name.toUri()));
-    }
-    return datas;
-  }
-
-  public static List<Interest> buildInterests(List<Name> names) {
-    List<Interest> interests = new ArrayList<>();
-    for (Name name : names) {
-      interests.add(buildInterest(name.toUri()));
-    }
-    return interests;
-  }
-
-  public static long timeAddDatas(Repository repo, List<Data> datas) {
-    long start = System.nanoTime();
-    for (Data data : datas) {
-      repo.put(data);
-    }
-    return System.nanoTime() - start;
-  }
-
-  public static long timeFindDatas(Repository repo, List<Interest> interests) throws DataNotFoundException {
-    long start = System.nanoTime();
-    for (Interest interest : interests) {
-      Data data = repo.get(interest);
-      assertNotNull(data);
-    }
-    return System.nanoTime() - start;
-  }
-
-  public static long timeFindChildSelectedDatas(Repository repo, List<Interest> interests) throws DataNotFoundException {
-    long start = System.nanoTime();
-    for (Interest interest : interests) {
-      interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
-      Data data = repo.get(interest);
-      assertNotNull(data);
-    }
-    return System.nanoTime() - start;
-  }
-
-
-  public static class NameGenerator implements Iterator<Name>, Iterable<Name> {
-
-    private int size;
-    private int count = 0;
-    private Name last = new Name();
-
-    public NameGenerator(int size) {
-      this.size = size;
-    }
-
-    @Override
-    public boolean hasNext() {
-      return count < size;
-    }
-
-    @Override
-    public Name next() {
-      int current = count % 26;
-      String letter = Character.toString((char) (current + 65));
-      if (current == 0) {
-        last.append(letter);
-      } else {
-        last = last.getPrefix(-1).append(letter);
-      }
-      count++;
-      return new Name(last);
-    }
-
-    @Override
-    public void remove() {
-      throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public Iterator<Name> iterator() {
-      return this;
-    }
-  }
-}
