@Override
 public boolean playerHasResearch(EntityPlayer ep, String key) {
   ChromaResearch r = ChromaResearch.getByName(key.toUpperCase());
   if (r == null) {
     ChromatiCraft.logger.logError(
         "A mod tried to fetch the state of an invalid research '" + key + "'!");
     Thread.dumpStack();
     return false;
   }
   return this.playerHasFragment(ep, r);
 }
 @Override
 public boolean lexiconHasFragment(ItemStack book, String key) {
   ChromaResearch r = ChromaResearch.getByName(key.toUpperCase());
   if (r == null) {
     ChromatiCraft.logger.logError(
         "A mod tried to fetch the state of an invalid research '" + key + "'!");
     Thread.dumpStack();
     return false;
   }
   return ItemChromaBook.hasPage(book, r);
 }
 @Override
 public HashSet<String> getPrerequisites(String key) {
   ChromaResearch r = ChromaResearch.getByName(key.toUpperCase());
   if (r == null) {
     ChromatiCraft.logger.logError(
         "A mod tried to fetch the state of an invalid research '" + key + "'!");
     Thread.dumpStack();
     return null;
   }
   Collection<ChromaResearch> c = this.getPreReqsFor(r);
   HashSet<String> h = new HashSet();
   for (ChromaResearch req : c) {
     h.add(req.name());
   }
   return h;
 }
 public Collection<ChromaResearch> getFragments(EntityPlayer ep) {
   Collection<ChromaResearch> c = new HashSet();
   NBTTagList li = this.getNBTFragments(ep);
   for (Object o : li.tagList) {
     ChromaResearch r = ChromaResearch.getByName(((NBTTagString) o).func_150285_a_());
     if (r != null) // may be null if a key is removed
     c.add(r);
   }
   return c;
 }