@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 boolean givePlayerFragment(EntityPlayer ep, ChromaResearch r, boolean notify) {
   if (!this.playerHasFragment(ep, r)) {
     this.getNBTFragments(ep).appendTag(new NBTTagString(r.name()));
     this.checkForUpgrade(ep);
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     if (notify) this.notifyPlayerOfProgression(ep, r);
     ProgressionCacher.instance.updateProgressCache(ep);
     MinecraftForge.EVENT_BUS.post(new ProgressionEvent(ep, r.name(), ResearchType.FRAGMENT));
     return true;
   }
   return false;
 }
 @Override
 public HashSet<String> getAllResearches() {
   HashSet<String> c = new HashSet();
   for (ChromaResearch r : ChromaResearch.getAllNonParents()) {
     c.add(r.name());
   }
   return c;
 }
 public boolean removePlayerFragment(EntityPlayer ep, ChromaResearch r, boolean notify) {
   if (this.playerHasFragment(ep, r)) {
     NBTTagList li = this.getNBTFragments(ep);
     Iterator<NBTTagString> it = li.tagList.iterator();
     while (it.hasNext()) {
       NBTTagString s = it.next();
       if (s.func_150285_a_().equals(r.name())) it.remove();
     }
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     ProgressionCacher.instance.updateProgressCache(ep);
     return true;
   }
   return false;
 }
 static {
   for (int i = 0; i < researchList.length; i++) {
     ChromaResearch r = researchList[i];
     if (!r.isDummiedOut()) {
       if (r.level != null) levelMap.addValue(r.level, r);
       byName.put(r.name(), r);
       if (r.isParent) parents.add(r);
       else nonParents.add(r);
     }
     ChromaResearch pre = duplicateChecker.get(r.getIDObject());
     if (pre != null)
       throw new RegistrationException(
           ChromatiCraft.instance,
           "Two research fragments have the same block/item/ability/etc: " + r + " & " + pre);
     duplicateChecker.put(r.getIDObject(), r);
     ChromaResearchManager.instance.register(r);
   }
 }