<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def copy(src, dst, only_update=False, copystat=True, cwd=None, dest_is_dir=False, create_dest_dirs=False, logger=None):
 """ Augmented shutil.copy with extra options and slightly modified behaviour Parameters ========== src: string path to source file dst: string path to destingation only_update: bool only copy if source is newer than destination (returns None if it was newer), default: False copystat: bool See shutil.copystat. default: True cwd: string Path to working directory (root of relative paths) dest_is_dir: bool ensures that dst is treated as a directory. default: False create_dest_dirs: bool creates directories if needed. logger: logging.Looger debug level info emitted. Passed onto make_dirs. Returns ======= Path to the copied file. """

    # Handle virtual working directory
    if cwd:
        if not os.path.isabs(src):
            src = os.path.join(cwd, src)
        if not os.path.isabs(dst):
            dst = os.path.join(cwd, dst)

    # Make sure source file extists
    if not os.path.exists(src):
        # Source needs to exist
        msg = "Source: `{}` does not exist".format(src)
        raise FileNotFoundError(msg)

    # We accept both (re)naming destination file _or_
    # passing a (possible non-existant) destination directory
    if dest_is_dir:
        if not dst[-1] == '/':
            dst = dst+'/'
    else:
        if os.path.exists(dst) and os.path.isdir(dst):
            dest_is_dir = True

    if dest_is_dir:
        dest_dir = dst
        dest_fname = os.path.basename(src)
        dst = os.path.join(dest_dir, dest_fname)
    else:
        dest_dir = os.path.dirname(dst)
        dest_fname = os.path.basename(dst)

    if not os.path.exists(dest_dir):
        if create_dest_dirs:
            make_dirs(dest_dir, logger=logger)
        else:
            msg = "You must create directory first."
            raise FileNotFoundError(msg)

    if only_update:
        if not missing_or_other_newer(dst, src):
            if logger:
                logger.debug(
                    "Did not copy {} to {} (source not newer)".format(
                        src, dst))
            return

    if os.path.islink(dst):
        if os.path.abspath(os.path.realpath(dst)) == \
           os.path.abspath(dst):
            pass  # destination is a symlic pointing to src
    else:
        if logger:
            logger.debug("Copying {} to {}".format(src, dst))
        shutil.copy(src, dst)
        if copystat:
            shutil.copystat(src, dst)
    return dst