docs: def merge_or_link(self, input_args, raw_folder, local_base="sample"):
          """
          This function standardizes various input possibilities by converting
          either .bam, .fastq, or .fastq.gz files into a local file; merging those
          if multiple files given.
  
          :param list input_args: This is a list of arguments, each one is a
              class of inputs (which can in turn be a string or a list).
              Typically, input_args is a list with 2 elements: first a list of
              read1 files; second an (optional!) list of read2 files.
          :param str raw_folder: Name/path of folder for the merge/link.
          :param str local_base: Usually the sample name. This (plus file
              extension) will be the name of the local file linked (or merged)
              by this function.
          """
          self.make_sure_path_exists(raw_folder)
  
          if not isinstance(input_args, list):
              raise Exception("Input must be a list")
  
          if any(isinstance(i, list) for i in input_args):
              # We have a list of lists. Process each individually.
              local_input_files = list()
              n_input_files = len(filter(bool, input_args))
              print("Number of input file sets:\t\t" + str(n_input_files))
  
              for input_i, input_arg in enumerate(input_args):
                  # Count how many non-null items there are in the list;
                  # we only append _R1 (etc.) if there are multiple input files.
                  if n_input_files > 1:
                      local_base_extended = local_base + "_R" + str(input_i + 1)
                  else:
                      local_base_extended = local_base
                  if input_arg:
                      out = self.merge_or_link(
                              input_arg, raw_folder, local_base_extended)
  
                      print("Local input file: '{}'".format(out))
                      # Make sure file exists:
                      if not os.path.isfile(out):
                          print("Not a file: '{}'".format(out))
  
                      local_input_files.append(out)
  
              return local_input_files
  
          else:
              # We have a list of individual arguments. Merge them.
  
              if len(input_args) == 1:
                  # Only one argument in this list. A single input file; we just link
                  # it, regardless of file type:
                  # Pull the value out of the list
                  input_arg = input_args[0]
                  input_ext = self.get_input_ext(input_arg)
  
                  # Convert to absolute path
                  if not os.path.isabs(input_arg):
                      input_arg = os.path.abspath(input_arg)
  
                  # Link it to into the raw folder
                  local_input_abs = os.path.join(raw_folder, local_base + input_ext)
                  self.pm.run(
                      "ln -sf " + input_arg + " " + local_input_abs,
                      target=local_input_abs,
                      shell=True)
                  # return the local (linked) filename absolute path
                  return local_input_abs
  
              else:
                  # Otherwise, there are multiple inputs.
                  # If more than 1 input file is given, then these are to be merged
                  # if they are in bam format.
                  if all([self.get_input_ext(x) == ".bam" for x in input_args]):
                      sample_merged = local_base + ".merged.bam"
                      output_merge = os.path.join(raw_folder, sample_merged)
                      cmd = self.merge_bams(input_args, output_merge)
                      self.pm.run(cmd, output_merge)
                      cmd2 = self.validate_bam(output_merge)
                      self.pm.run(cmd, output_merge, nofail=True)
                      return output_merge
  
                  # if multiple fastq
                  if all([self.get_input_ext(x) == ".fastq.gz" for x in input_args]):
                      sample_merged_gz = local_base + ".merged.fastq.gz"
                      output_merge_gz = os.path.join(raw_folder, sample_merged_gz)
                      #cmd1 = self.ziptool + "-d -c " + " ".join(input_args) + " > " + output_merge
                      #cmd2 = self.ziptool + " " + output_merge
                      #self.pm.run([cmd1, cmd2], output_merge_gz)
                      # you can save yourself the decompression/recompression:
                      cmd = "cat " + " ".join(input_args) + " > " + output_merge_gz 
                      self.pm.run(cmd, output_merge_gz)
                      return output_merge_gz
  
                  if all([self.get_input_ext(x) == ".fastq" for x in input_args]):
                      sample_merged = local_base + ".merged.fastq"
                      output_merge = os.path.join(raw_folder, sample_merged)
                      cmd = "cat " + " ".join(input_args) + " > " + output_merge
                      self.pm.run(cmd, output_merge)
                      return output_merge
  
                  # At this point, we don't recognize the input file types or they
                  # do not match.
                  raise NotImplementedError(
                          "Input files must be of the same type, and can only "
                          "merge bam or fastq.")