def join_paired_end_reads_fastqjoin(
        reads1_infile_path,
        reads2_infile_path,
        perc_max_diff=None,  # typical default is 8
        min_overlap=None,  # typical default is 6
        outfile_label='fastqjoin',
        params={},
        working_dir=tempfile.gettempdir(),
        SuppressStderr=True,
        SuppressStdout=True,
        HALT_EXEC=False):
    """ Runs fastq-join, with default parameters to assemble paired-end reads.
        Returns file path string.

        -reads1_infile_path : reads1.fastq infile path
        -reads2_infile_path : reads2.fastq infile path
        -perc_max_diff : maximum % diff of overlap differences allowed
        -min_overlap : minimum allowed overlap required to assemble reads
        -outfile_label : base name for output files.
        -params : dictionary of application controller parameters

    """
    abs_r1_path = os.path.abspath(reads1_infile_path)
    abs_r2_path = os.path.abspath(reads2_infile_path)

    infile_paths = [abs_r1_path, abs_r2_path]

    # check / make absolute infile paths
    for p in infile_paths:
        if not os.path.exists(p):
            raise IOError('File not found at: %s' % p)

    fastq_join_app = FastqJoin(params=params,
                               WorkingDir=working_dir,
                               SuppressStderr=SuppressStderr,
                               SuppressStdout=SuppressStdout,
                               HALT_EXEC=HALT_EXEC)

    # set param. Helps with QIIME integration to have these values
    # set to None by default. This way we do not have to worry
    # about changes in default behaviour of the wrapped
    # application
    if perc_max_diff is not None:
        if isinstance(perc_max_diff, int) and 0 <= perc_max_diff <= 100:
            fastq_join_app.Parameters['-p'].on(perc_max_diff)
        else:
            raise ValueError("perc_max_diff must be int between 0-100!")

    if min_overlap is not None:
        if isinstance(min_overlap, int) and 0 < min_overlap:
            fastq_join_app.Parameters['-m'].on(min_overlap)
        else:
            raise ValueError("min_overlap must be an int >= 0!")

    if outfile_label is not None:
        if isinstance(outfile_label, str):
            fastq_join_app.Parameters['-o'].on(outfile_label + '.')
        else:
            raise ValueError("outfile_label must be a string!")
    else:
        pass

    # run assembler
    result = fastq_join_app(infile_paths)

    # Store output file path data to dict
    path_dict = {}
    path_dict['Assembled'] = result['Assembled'].name
    path_dict['UnassembledReads1'] = result['UnassembledReads1'].name
    path_dict['UnassembledReads2'] = result['UnassembledReads2'].name

    # sanity check that files actually exist in path lcoations
    for path in path_dict.values():
        if not os.path.exists(path):
            raise IOError('Output file not found at: %s' % path)

    # fastq-join automatically appends: 'join', 'un1', or 'un2'
    # to the end of the file names. But we want to rename them so
    # they end in '.fastq'. So, we iterate through path_dict to
    # rename the files and overwrite the dict values.
    for key, file_path in path_dict.items():
        new_file_path = file_path + '.fastq'
        shutil.move(file_path, new_file_path)
        path_dict[key] = new_file_path

    return path_dict
Runs fastq-join, with default parameters to assemble paired-end reads.
        Returns file path string.

        -reads1_infile_path : reads1.fastq infile path
        -reads2_infile_path : reads2.fastq infile path
        -perc_max_diff : maximum % diff of overlap differences allowed
        -min_overlap : minimum allowed overlap required to assemble reads
        -outfile_label : base name for output files.
        -params : dictionary of application controller parameters