anchor.diff:  let
     # FIXME: workaround until https://github.com/NixOS/nixpkgs/pull/162246 lands
     cleanName = if lib.hasInfix " " name
  -                then throw "Name must not contain spaces!"
  +                then throw "makeDesktopItem: name must not contain spaces!"
                   else name;
   
     # There are multiple places in the FDO spec that make "boolean" values actually tristate,
  
positive.code:     "NoDisplay" = boolOrNullToString noDisplay;
      "Comment" = comment;
      "Icon" = icon;
      "OnlyShowIn" = renderList onlyShowIn;
      "NotShowIn" = renderList notShowIn;
      "DBusActivatable" = boolOrNullToString dbusActivatable;
      "TryExec" = tryExec;
      "Exec" = exec;
      "Path" = path;
      "Terminal" = boolOrNullToString terminal;
      "Actions" = renderList (builtins.attrNames actions);
      "MimeType" = renderList mimeTypes;
      "Categories" = renderList categories;
      "Implements" = renderList implements;
      "Keywords" = renderList keywords;
      "StartupNotify" = boolOrNullToString startupNotify;
      "StartupWMClass" = startupWMClass;
      "URL" = url;
  
negative.code:   boolOrNullToString = value:
      if value == null then null
      else if builtins.isBool value then lib.boolToString value
      else throw "makeDesktopItem: value must be a boolean or null!";
  
    # Multiple values are represented as one string, joined by semicolons.
    # Technically, it's possible to escape semicolons in values with \;, but this is currently not implemented.
    renderList = key: value:
      if !builtins.isList value then throw "makeDesktopItem: value for ${key} must be a list!"
      else if builtins.any (item: lib.hasInfix ";" item) value then throw "makeDesktopItem: values in ${key} list must not contain semicolons!"
      else if value == [] then null
      else builtins.concatStringsSep ";" value;
  
  