protected override void finish()
        {
            base.finish();

            if (_trackFactory != null)
            {
                _trackFactory.Dispose();
                _trackFactory = null;
            }
        }
        protected override bool workOnDevice()
        {
            bool isMetaPlayListName = IPodTrackFormatter.HasMetaInfo(_targetPlayListName);

            if (!isMetaPlayListName) createPlayList(_targetPlayListName);

            _trackFactory = new IPodTrackFactory();

            notProcessedItems.Clear();

            // add notProcessedItems logic

            var fse = new FileSystemEnumerator(_source, _files);

            var copyList = new List<string>();

            ProgressFormHelper.Invoke(f =>
            {
                copyList = fse.FetchFiles().ToList();
            },
            MsgStr.MsgGettingFiles);

            // critical !!!
            if (ProgressFormHelper.LastError != null)
                throw ProgressFormHelper.LastError;

            int progress = 0;
            int totalCount = copyList.Count;

            totalByteToCopy = fse.TotalFileSize;

            foreach (string fileName in copyList)
            {
                if (!canExecute()) return false;

                setProgress(progress++, totalCount);

                if (!tryDo(() =>
                    {
                        _newTrack = _trackFactory.Get(fileName);
                    },
                    canSkip: true,
                    obj: fileName)) continue;

                if (_newTrack == null) continue;

                if (isMetaPlayListName) createPlayList(IPodTrackFormatter.Get(_newTrack, _targetPlayListName));

                if (ifTargetExist()) continue;

                // copy track local before adding
                string newFileName = Path.Combine(
                    device.FileSystem.IPodControlPath,
                    Path.GetRandomFileName() + Path.GetExtension(fileName));

                if (!copyFile(fileName, newFileName)) continue;

                if (!canExecute()) return false;

                // why ???
                //_newTrack.FilePath = newFileName;

                Track addedTrack = null;

                // try add track to device
                if (tryDo(() =>
                    {
                        addedTrack = device.Tracks.Add(_newTrack);
                    },
                    canSkip: true,
                    obj: _newTrack))
                {
                    // if added
                    if (!_targetPlaylist.IsMaster)
                    {
                        tryDo(() => _targetPlaylist.AddTrack(addedTrack), canSkip: true, obj: addedTrack);
                    }

                    if (isMoveOperation)
                    {
                        // remove original file on move
                        tryDo(() =>
                        {
                            File.SetAttributes(_newTrack.FilePath, FileAttributes.Normal);
                            File.Delete(_newTrack.FilePath);
                        },
                        canSkip: true,
                        obj: _newTrack.FilePath);
                    }
                }
                else
                {
                    // if not remove tmp-copy file
                    if (File.Exists(newFileName))
                    {
                        tryDo(() =>
                        {
                            File.SetAttributes(newFileName, FileAttributes.Normal);
                            File.Delete(newFileName);
                        },
                        canSkip: true,
                        obj: newFileName);
                    }
                }
            }

            if (isMoveOperation)
            {
                // remvoe dirs on move file
                foreach (string dir in fse.GetBypassDirectores())
                {
                    if (!canExecute()) return false;

                    if (Directory.GetFiles(dir).Length == 0)
                    {
                        tryDo(() => Directory.Delete(dir), canSkip: true, obj: dir);
                    }
                }
            }

            return true;
        }