Downloads the given memory dump into the given directory.  Returns a tuple of a list of files extracted from what was downloaded, and the path to the combined memory dump.

def download_memory_dump(self, sha256, environment_id, dest_dir):
        """Downloads the given memory dump into the given directory.  Returns a tuple of a list of files extracted from what was downloaded, and the path to the combined memory dump."""

        dest_path = os.path.join(dest_dir, 'memory.zip')
        if self.download(sha256, environment_id, VXSTREAM_DOWNLOAD_MEMORY, dest_path) is None:
            return None

        with open(dest_path, 'rb') as fp:
            blob = fp.read(1024)
            if b'No dump files available' in blob:
                logging.debug("memory dump not available for {} env {}".format(sha256, environment_id))
                return None

        logging.debug("extracting memory dump {} into {}".format(dest_path, dest_dir))
        p = Popen(['7z', 'x', '-y', '-o{}'.format(dest_dir), dest_path], stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()

        file_list = []
        for file_path in [os.path.join(dest_dir, f) for f in os.listdir(dest_dir) if f != "memory.zip"]:
            file_list.append(file_path)

        # concatenate all these files into one file
        dest_path = os.path.join(dest_dir, 'memory.combined.mdmp')
        for file_path in file_list:
            logging.debug("concatenating {}".format(file_path))
            with open(file_path, 'rb') as input_fp:
                with open(dest_path, 'ab') as output_fp:
                    while True:
                        data = input_fp.read(io.DEFAULT_BUFFER_SIZE)
                        if data == b'':
                            break

                        output_fp.write(data)

        return file_list, dest_path