private PluginInfo<Command> createEntry(
      final Object key, final Hashtable<?, ?> commands, final Map<String, MenuPath> menuTable) {
    final String ij1PluginString = commands.get(key).toString();

    // NB: Check whether legacy command is on the blacklist.
    final boolean blacklisted = blacklist.contains(ij1PluginString);

    // NB: Check whether menu path is already taken by a modern ImageJ command.
    // This allows transparent override of legacy commands.
    final MenuPath menuPath = menuTable.get(key);
    final boolean overridden = menuPath != null && appMenu.getMenu(menuPath) != null;

    if (log.isDebug()) {
      // output discovery info for this legacy command
      final String status;
      if (blacklisted && overridden) status = "[BLACKLISTED, OVERRIDDEN] ";
      else if (blacklisted) status = "[BLACKLISTED] ";
      else if (overridden) status = "[OVERRIDDEN] ";
      else status = "";
      log.debug(
          "- "
              + status
              + ij1PluginString
              + " [menu = "
              + (menuPath == null
                  ? ""
                  : menuPath.getMenuString() + ", weight = " + menuPath.getLeaf().getWeight())
              + "]");
    }
    if (blacklisted && overridden) {
      log.warn("Overridden plugin " + ij1PluginString + " is blacklisted");
    }

    if (blacklisted || overridden) return null;

    final String className = parsePluginClass(ij1PluginString);
    final String arg = parseArg(ij1PluginString);

    final Map<String, Object> presets = new HashMap<String, Object>();
    presets.put("className", className);
    presets.put("arg", arg);
    final CommandInfo ci = new CommandInfo(LegacyCommand.class);
    // HACK: Make LegacyCommands a subtype of regular Commands.
    ci.setPluginType(legacyCommandClass());
    if (menuPath != null) ci.setMenuPath(menuPath);
    ci.setPresets(presets);

    // flag legacy command with special icon
    if (menuPath != null) menuPath.getLeaf().setIconPath(LEGACY_PLUGIN_ICON);

    return ci;
  }