private void performStatusChange(final FTPDownloadThread source, final FTPDownloadThread.State state) {
        final boolean finished = (state == FTPDownloadThread.State.Finished);
        boolean merge = false;

        //ignore these states, because they are set from this class
        if (state != FTPDownloadThread.State.Merging) {
            if (finished) {
                synchronized (mWorkingThreads) {
                    mWorkingThreads.remove(source);
                }
                //finished is called here or in download thread if not separated and file with same size is found
                //on local drive
            } else {
                synchronized (mWorkingThreads) {
                    if (source.getParentTask() != this) {
                        System.err.println("This thread is not from this task!" + source.getContext().toString());
                        return;
                    } else {
                        if (state == FTPDownloadThread.State.Downloaded) {
                            mWorkingThreads.remove(source);
                        } else {
                            if (!mWorkingThreads.contains(source)) {
                                //can be restarted, finished are handled before
                                mWorkingThreads.add(source);
                            }
                        }
                    }
                }
            }
            merge = mWorkingThreads.size() == 0 && mData.size() > 1;
            //we are done in this task, now is time to merge
            if (merge) {
                if(!mIsMerging){
                    synchronized (this){
                        if(!mIsMerging){
                            mIsMerging = true;
                            //must be called in diff thread to let finish current downloading thread
                            performMerge();
                        }
                    }
                }

            }
        }
    }