params: with params;
# combine =
args@{
  pkgFilter ? (pkg: pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "core")
, extraName ? "combined", ...
}:
let
  pkgSet = removeAttrs args [ "pkgFilter" "extraName" ] // {
    # include a fake "core" package
    core.pkgs = [
      (bin.core.out // { pname = "core"; tlType = "bin"; })
      (bin.core.doc // { pname = "core"; tlType = "doc"; })
    ];
  };
  pkgList = rec {
    all = lib.filter pkgFilter (combinePkgs pkgSet);
    splitBin = lib.partition (p: p.tlType == "bin") all;
    bin = mkUniquePkgs splitBin.right;
    nonbin = mkUniquePkgs splitBin.wrong;

    # extra interpreters needed for shebangs, based on 2015 schemes "medium" and "tetex"
    # (omitted tk needed in pname == "epspdf", bin/epspdftk)
    pkgNeedsPython = pkg: pkg.tlType == "run" && lib.elem pkg.pname
      [ "de-macro" "pythontex" "dviasm" "texliveonfly" ];
    pkgNeedsRuby = pkg: pkg.tlType == "run" && pkg.pname == "match-parens";
    extraInputs =
      lib.optional (lib.any pkgNeedsPython splitBin.wrong) python
      ++ lib.optional (lib.any pkgNeedsPython splitBin.wrong) ruby;
  };

  mkUniquePkgs = pkgs: fastUnique (a: b: a < b)
    # here we deal with those dummy packages needed for hyphenation filtering
    (map (p: if lib.isDerivation p then builtins.toPath p else "") pkgs);

in buildEnv {
  name = "texlive-${extraName}-${bin.texliveYear}";

  extraPrefix = "/share/texmf";

  ignoreCollisions = false;
  paths = pkgList.nonbin;

  buildInputs = [ makeWrapper ] ++ pkgList.extraInputs;

  postBuild = ''
    cd "$out"
    mkdir -p ./bin
  '' +
    lib.concatMapStrings
      (path: ''
        for f in '${path}'/bin/*; do
          if [[ -L "$f" ]]; then
            cp -d "$f" ./bin/
          else
            ln -s "$f" ./bin/
          fi
        done
      '')
      pkgList.bin
    +
  ''
    export PATH="$out/bin:$out/share/texmf/scripts/texlive:${perl}/bin:$PATH"
    export TEXMFCNF="$out/share/texmf/web2c"
    export TEXMFDIST="$out/share/texmf"
    export TEXMFSYSCONFIG="$out/share/texmf-config"
    export TEXMFSYSVAR="$out/share/texmf-var"
    export PERL5LIB="$out/share/texmf/scripts/texlive"
  '' +
    # patch texmf-dist -> texmf to be sure
    # TODO: cleanup the search paths incl. SELFAUTOLOC, and perhaps do lua actions?
    # tried inspiration from install-tl, sub do_texmf_cnf
  ''
    (
      cd ./share/texmf/web2c/
      local cnfOrig="$(realpath ./texmf.cnf)"
      rm ./texmf.cnf
      cat "$cnfOrig" | sed 's/texmf-dist/texmf/g' > ./texmf.cnf

      rm updmap.cfg
    )
  '' +
    # updmap.cfg seems like not needing changes

    # now filter hyphenation patterns, in a hacky way ATM
  ''
    (
      local script='${
        lib.concatMapStrings (pkg: "/^\% from ${pkg.pname}/,/^\%/p;\n")
          pkgList.splitBin.wrong
      } 1,/^\% from/p;'
      cd ./share/texmf/tex/generic/config/
      for fname in language.dat language.def; do
        [ -e $fname ] || continue;
        cnfOrig="$(realpath ./$fname)"
        rm ./$fname
        cat "$cnfOrig" | sed -n "$script" > ./$fname
      done
    )
  '' +

  # function to wrap created executables with required env vars
  ''
    wrapBin() {
    for link in ./bin/*; do
      [ -L "$link" -a -x "$link" ] || continue # if not link, assume OK
      local target=$(readlink "$link")

      # skip simple local symlinks; mktexfmt in particular
      echo "$target" | grep / > /dev/null || continue;

      echo -n "Wrapping '$link'"
      rm "$link"
      makeWrapper "$target" "$link" \
        --prefix PATH : "$out/bin:${perl}/bin" \
        --set TEXMFCNF "$out/share/texmf/web2c" \
        --set TEXMFDIST "$out/share/texmf" \
        --set TEXMFSYSCONFIG "$out/share/texmf-config" \
        --set TEXMFSYSVAR "$out/share/texmf-var" \
        --prefix PERL5LIB : "$out/share/texmf/scripts/texlive"

      # avoid using non-nix shebang in $target by calling interpreter
      if [[ "$(head -c 2 $target)" = "#!" ]]; then
        local cmdline="$(head -n 1 $target | sed 's/^\#\! *//;s/ *$//')"
        local relative=`basename "$cmdline" | sed 's/^env //' `
        local newInterp=`echo "$relative" | cut -d\  -f1`
        local params=`echo "$relative" | cut -d\  -f2- -s`
        local newPath="$(type -P $newInterp)"
        if [[ -z "$newPath" ]]; then
          echo " Warning: unknown shebang '$cmdline' in '$target'"
          continue
        fi
        echo " and patching shebang '$cmdline'"
        sed "s|^exec |exec $newPath $params |" -i "$link"
      else
        sed 's|^exec |exec -a "$0" |' -i "$link"
        echo
      fi
    done
    }
  '' +
  # texlive post-install actions
  ''
    mkdir -p "$out/share/texmf/scripts/texlive/"
    ln -s '${bin.core.out}/share/texmf-dist/scripts/texlive/TeXLive' "$out/share/texmf/scripts/texlive/"

    for tool in updmap; do
      ln -sf "$out/share/texmf/scripts/texlive/$tool."* "$out/bin/$tool"
    done
  '' +
    # now hack to preserve "$0" for mktexfmt
  ''
    cp "$out"/share/texmf/scripts/texlive/fmtutil.pl "$out/bin/fmtutil"
    patchShebangs "$out/bin/fmtutil"
    sed "1s|$| -I $out/share/texmf/scripts/texlive|" -i "$out/bin/fmtutil"
    ln -sf fmtutil "$out/bin/mktexfmt"

    perl `type -P mktexlsr.pl` ./share/texmf
    texlinks.sh "$out/bin" && wrapBin
    perl `type -P fmtutil.pl` --sys --refresh | grep '^fmtutil' # too verbose
    #texlinks.sh "$out/bin" && wrapBin # do we need to regenerate format links?
    perl `type -P updmap.pl` --sys --syncwithtrees --force
    perl `type -P mktexlsr.pl` ./share/texmf-* # to make sure
  '' +
    # install (wrappers for) scripts, based on a list from upstream texlive
  ''
    (
      cd "$out/share/texmf/scripts"
      source '${bin.core.out}/share/texmf-dist/scripts/texlive/scripts.lst'
      for s in $texmf_scripts; do
        [[ -x "./$s" ]] || continue
        tName="$(basename $s | sed 's/\.[a-z]\+$//')" # remove extension
        [[ ! -e "$out/bin/$tName" ]] || continue
        ln -sv "$(realpath $s)" "$out/bin/$tName" # wrapped below
      done
    )
    rm "$out"/bin/*-sys
    wrapBin
  '' +
  # TODO: a context trigger https://www.preining.info/blog/2015/06/debian-tex-live-2015-the-new-layout/
    # http://wiki.contextgarden.net/ConTeXt_Standalone#Unix-like_platforms_.28Linux.2FMacOS_X.2FFreeBSD.2FSolaris.29

    # I would just create links from "$out"/share/{man,info},
    #   but buildenv has problems with merging symlinks with directories;
    #   note: it's possible we might need deepen the work-around to man/*.
  ''
    for d in {man,info}; do
      [[ -e "./share/texmf/doc/$d" ]] || continue;
      (
        mkdir -p "./share/$d" && cd "./share/$d"
        ln -s -t . ../texmf/doc/"$d"/*
      )
    done
  ''
    + bin.cleanBrokenLinks
  ;
}
# TODO: make TeX fonts visible by fontconfig: it should be enough to install an appropriate file
#       similarly, deal with xe(la)tex font visibility?

