# Buggy code
def _MoveDownload(self, download_state, new_dir):
    def rename_or_merge(old, new):
        if os.path.exists(old):
            if os.path.exists(new):
                files = os.listdir(old)
                for file in files:
                    oldfile = os.path.join(old, file)
                    newfile = os.path.join(new, file)

                    if os.path.isdir(oldfile):
                        self.rename_or_merge(oldfile, newfile)

                    elif os.path.exists(newfile):
                        os.remove(newfile)
                        shutil.move(oldfile, newfile)
                    else:
                        shutil.move(oldfile, newfile)
            else:
                os.renames(old, new)

    destdirs = download_state.get_download().get_dest_files()
    if len(destdirs) > 1:
        old = os.path.commonprefix([os.path.split(path)[0] for _, path in destdirs])
        _, old_dir = new = os.path.split(old)
        new = os.path.join(new_dir, old_dir)
    else:
        old = destdirs[0][1]
        _, old_file = os.path.split(old)
        new = os.path.join(new_dir, old_file)

    self._logger.info("Creating new downloadconfig")

    # Move torrents
    storage_moved = False

    download = download_state.get_download()
    self._logger.info("Moving from %s to %s newdir %s", old, new, new_dir)
    download.move_storage(new_dir)
    if download.get_save_path() == new_dir:
        storage_moved = True

    # If libtorrent hasn't moved the files yet, move them now
    if not storage_moved:
        self._logger.info("Moving from %s to %s newdir %s", old, new, new_dir)
        movelambda = lambda: rename_or_merge(old, new)
        self.guiutility.utility.session.lm.threadpool.add_task(movelambda, 0.0)


# Traceback (isError)
Regression

Tribler.Test.Core.Modules.RestApi.test_downloads_endpoint.TestDownloadsEndpoint.test_remove_download_no_remove_data_param (from nosetests)
Failing for the past 1 build (Since Failed#2109 )
Took 4.4 sec.
Error Message

Test raised 1 unhandled Twisted exceptions:
[{'log_namespace': u'log_legacy', 'log_time': 1467938979.639, 'format': '%(log_legacy)s', 'log_system': '-', 'log_legacy': <twisted.logger._stdlib.StringifiableFromEvent object at 0x06D22830>, 'log_level': <LogLevel=critical>, 'system': '-', 'isError': 1, 'failure': <twisted.python.failure.Failure exceptions.AttributeError: 'NoneType' object has no attribute 'add_task'>, 'time': 1467938979.639, 'log_text': 'Unhandled Error\nTraceback (most recent call last):\n  File "C:\\Python27\\lib\\threading.py", line 763, in run\n    self.__target(*self.__args, **self.__kwargs)\n  File "C:\\workspace\\jenkins\\workspace\\GH_Tribler_PR_tests_win32\\tribler\\Tribler\\Core\\Utilities\\twisted_thread.py", line 55, in _reactor_runner\n    reactor.run(installSignalHandlers=False)\n  File "C:\\Python27\\lib\\site-packages\\twisted\\internet\\base.py", line 1194, in run\n    self.mainLoop()\n  File "C:\\Python27\\lib\\site-packages\\twisted\\internet\\base.py", line 1203, in mainLoop\n    self.runUntilCurrent()\n--- <exception caught here> ---\n  File "C:\\Python27\\lib\\site-packages\\twisted\\internet\\base.py", line 825, in runUntilCurrent\n    call.func(*call.args, **call.kw)\n  File "C:\\workspace\\jenkins\\workspace\\GH_Tribler_PR_tests_win32\\tribler\\Tribler\\Core\\Libtorrent\\__init__.py", line 27, in <lambda>\n    lambda_f = lambda a = args, kwa = kwargs: invoke_func(*a, **kwa)\n  File "C:\\workspace\\jenkins\\workspace\\GH_Tribler_PR_tests_win32\\tribler\\Tribler\\Core\\Libtorrent\\__init__.py", line 28, in invoke_func\n    download.session.lm.threadpool.add_task(lambda_f, 1)\nexceptions.AttributeError: \'NoneType\' object has no attribute \'add_task\'\n', 'log_format': u'{log_text}', 'message': (), 'why': None}]

# Fixed code
def _MoveDownload(self, download_state, new_dir):
    def rename_or_merge(old, new):
        if os.path.exists(old):
            if os.path.exists(new):
                files = os.listdir(old)
                for file in files:
                    oldfile = os.path.join(old, file)
                    newfile = os.path.join(new, file)

                    if os.path.isdir(oldfile):
                        self.rename_or_merge(oldfile, newfile)

                    elif os.path.exists(newfile):
                        os.remove(newfile)
                        shutil.move(oldfile, newfile)
                    else:
                        shutil.move(oldfile, newfile)
            else:
                os.renames(old, new)

    destdirs = download_state.get_download().get_dest_files()
    if len(destdirs) > 1:
        old = os.path.commonprefix([os.path.split(path)[0] for _, path in destdirs])
        _, old_dir = new = os.path.split(old)
        new = os.path.join(new_dir, old_dir)
    else:
        old = destdirs[0][1]
        _, old_file = os.path.split(old)
        new = os.path.join(new_dir, old_file)

    self._logger.info("Creating new downloadconfig")

    # Move torrents
    storage_moved = False

    download = download_state.get_download()
    self._logger.info("Moving from %s to %s newdir %s", old, new, new_dir)
    download.move_storage(new_dir)
    if download.get_save_path() == new_dir:
        storage_moved = True

    # If libtorrent hasn't moved the files yet, move them now
    if not storage_moved:
        self._logger.info("Moving from %s to %s newdir %s", old, new, new_dir)
        reactor.callFromThread(rename_or_merge, old, new)