docs: public static Set<HeadedSyntacticCategory> getSyntacticCategoryClosure(
        Collection<HeadedSyntacticCategory> syntacticCategories) {
      Set<String> featureValues = Sets.newHashSet();
      for (HeadedSyntacticCategory cat : syntacticCategories) {
        getAllFeatureValues(cat.getSyntax(), featureValues);
      }
  
      // Compute the closure of syntactic categories, assuming the only
      // operations are function application and feature assignment.
      Queue<HeadedSyntacticCategory> unprocessed = new LinkedList<HeadedSyntacticCategory>();
      unprocessed.addAll(syntacticCategories);
      
      Set<HeadedSyntacticCategory> allCategories = Sets.newHashSet();
      while (unprocessed.size() > 0) {
        HeadedSyntacticCategory cat = unprocessed.poll();
        Preconditions.checkArgument(cat.isCanonicalForm());
        
        allCategories.addAll(canonicalizeCategories(cat.getSubcategories(featureValues)));
        
        if (!cat.isAtomic()) {
          HeadedSyntacticCategory ret = cat.getReturnType().getCanonicalForm();
          if (!allCategories.contains(ret) && !unprocessed.contains(ret)) {
            unprocessed.offer(ret);
          }
  
          HeadedSyntacticCategory arg = cat.getArgumentType().getCanonicalForm();
          if (!allCategories.contains(arg) && !unprocessed.contains(arg)) {
            unprocessed.offer(arg);
          }
        }
      }
  
      // XXX: jayantk 1/8/2016 I think this loop does exactly the same thing as 
      // the previous one.
      /*
      Set<HeadedSyntacticCategory> allCategories = Sets.newHashSet();
      for (HeadedSyntacticCategory cat : syntacticCategories) {
        Preconditions.checkArgument(cat.isCanonicalForm());
        allCategories.addAll(canonicalizeCategories(cat.getSubcategories(featureValues)));
  
        while (!cat.getSyntax().isAtomic()) {
          allCategories.addAll(canonicalizeCategories(cat.getArgumentType().getCanonicalForm().getSubcategories(featureValues)));
          allCategories.addAll(canonicalizeCategories(cat.getReturnType().getCanonicalForm().getSubcategories(featureValues)));
          cat = cat.getReturnType();
        }
      }
      */
  
      return allCategories;
    }